I want to understand why using .flatMap() with async does not return a flatten array.
For example, for Typescript, this returns an array of numbers:
I know Promisse.all and async are useless with a simple array of number, it is just easier for reproduction
const numbers = [[1], [2], [3]];
// typed as number[]
const numbersFlatten = await Promise.all(
numbers.flatMap((number) => number),
);
When this, for Typescript, returns an array of array of numbers (just added an async) :
const numbers = [[1], [2], [3]];
// typed as number[][]
const numbersFlatten = await Promise.all(
numbers.flatMap(async (number) => number),
);
All async functions implicitly return Promises. By making your .flatMap() callback async, it now returns a Promise that resolves to the number from your array. For .flatMap() to work correctly and for it to flatten its results, the callback should return an array, not a Promise. Below is an example of the problematic behaviour:
const numbers = [[1], [2], [3]];
const promiseAllArg = numbers.flatMap(async (number) => number); // same as `.flatMap(number => Promise.resolve(number))`, flatMap doesn't know how to flatten `Promise<number>` into a resulting array
console.log(promiseAllArg); // [Promise<[1]>, Promise<[2]>, Promise<[3]>]
Instead, you can use a regular .map() call to obtain a nested array of resolved values followed by a .flat() call:
(async () => {
const numbers = [[1], [2], [3]];
const awaitedNumbers = await Promise.all(
numbers.map(async (number) => number) // some async code
);
const numbersFlattened = awaitedNumbers.flat() // flatten the resolved values
console.log(numbersFlattened);
})();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With