Consider the following code which print messages to console after I/O operations complete, in theory.
const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];
const promiseArray = array.map(arr => {
arr.map(num => {
return (async () => {
await foo(num);
console.log(num);
});
});
}).flat();
await Promise.all(promiseArray);
I don't know why but it doesn't work. Nothing was printed to the console.
However it would work if I wrap the async function within a Promise constructor
const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];
const promiseArray = array.map(arr => {
arr.map(num => {
return new Promise(async () => {
await foo(num);
console.log(num);
});
});
}).flat();
await Promise.all(promiseArray);
How should I rewrite the code to get rid of the Promise constructor?
1. Wait for all promises to complete with Promise.all Promise.all accepts an array of promises and returns a new promise that resolves only when all of the promises in the array have been resolved. The promise resolves to an array of all the values that the each of the promise returns.
Example: Following is the pseudo code (not runnable one) which will help you to understand more about Promise.all (). Async-await are the two keywords which we use to illustrate a particular function or method as asynchronous data acceptor.
If we pass async functions to forEach, we have no way of retrieving the returned promise to do anything useful with it. Unless you want to fire the async function and forget about it, passing async functions to forEach is never something you want to do. There you go! That is all 5 cheatsheets on what to do and not to do with an array of Promises.
Syntax: Following is the syntax which we could use in order to execute Promise.all () method for several promises: Promise.all ( [ first_promise , second_promise, .......])
Promise.all
takes an array of promises as its argument, not an array of async function
s. Also you were missing a return
statement. You should write
const promiseArray = array.flatMap(arr => {
return arr.map(async num => {
await foo(num);
console.log(num);
});
});
await Promise.all(promiseArray);
or
const promiseArray = array.map(async arr => {
await Promise.all(arr.map(async num => {
await foo(num);
console.log(num);
}));
});
await Promise.all(promiseArray);
Its normal Promise.all take an array of Promises, async function are of type function, but returns a Promise once invoked if no explicite return it will return a resolved promise with undefined value.
async function myAsyncFunction(){
return 1;
}
console.log(typeof myAsyncFunction)
console.log(typeof myAsyncFunction())
console.log(myAsyncFunction() instanceof Promise)
You are returning a function from map callback, not a promise. instead return foo(num)
. then after flattening you have an array of promises.
const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];
const promiseArray = array.map(arr => {
return arr.map(foo); // its equal arr.map(num => foo(num));
}).flat();
const results = await Promise.all(promiseArray);
results.forEach(item => console.log(item));
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