Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: asl.map produces return type of Promise to array of Promises #910

Open
dmeehan1968 opened this issue Oct 26, 2023 · 1 comment
Open

Comments

@dmeehan1968
Copy link

dmeehan1968 commented Oct 26, 2023

Example code

const migratedItems = await asl.map({
    items: scanResult.Items,
    iterator: async (item) => {
        return await migrateItem(item)
    },
})

If migrateItem() is defined as migrateItem(item: Record<string, AttributeValue>): Promise<Record<string, AttributeValue>> {...}, then the return type from asl.map is Promise<Promise<Record<string, AttributeValue>>[]> (promise for array of promises). In the example code, another await would be required to resolve back to the actual resolved value.

It seems that the definition of Map<Input,Output>'s iterator is incorrect in not mentioning Promise. The following definition produces the correct output (paraphrased) whilst allowing the iterator to be async or not.

interface Map<I,O> { 
    items: I[], 
    iterator: (item: I) => Promise<O> | O
    //...
}

const map = async <I,O>(args: Map<I,O): Promise<O[]> => {
    return {} as O[]
}

It may be possible to force the correct type using coercion (as a workaround):

const migratedItems = (await asl.map({
    items: scanResult.Items,
    iterator: async (item) => {
        return await migrateItem(item)
    },
})) as unknown as Record<string, AttributeValue>[]
@dmeehan1968
Copy link
Author

dmeehan1968 commented Oct 26, 2023

I realised that I should probably be using Promise.all (if I was writing typescript) but this produces an error:

        const migratedItems = await Promise.all(await asl.map({
            items: scanResult.Items,
            iterator: async (item) => {

                return await migrateItem(item)

            },
        }))

Error:

    Error: promise.all statement must have array literal expression as argument

    Kind: CallExpression
    Source: Promise.all(await asl.map({
                items: scanResult.Items,
                iterator: async (item) => {

                    return await migrateItem(item)

                },
            }))

This seems at odds with:

await asl.sdk(DynamoDB).batchWriteItem({
    parameters: {
        RequestItems: {
            'MyTableName': await Promise.all(scanResult.Items.map(async (item) => ({
                PutRequest: {
                    Item: await migrateItem(item),
                }
            })))
        }
    }
})

Note #911 prevents use of a computed table name.

The difference between asl.map and Array.map is that the former allows for concurrency control via the maxConcurrency property, whilst the latter uses Map defaults, which is unconstrained concurrency. Not being able to wrap asl.map in Promise.all means that there is no option to control concurrency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant