Reputation: 292
Is there some way to call asynchronous function in NOT for
loop (e.g. foreach, map) using async/await
and continue execution of the rest code only after all asynchronous functions completed?
const layers = ["layer1", "layer2", "layer3"];
async function connect(layer: string): Promise<object> {
return new Promise((resolve, reject) => {
setTimeout(function () {
resolve(layer);
}, 1000);
});
}
(async function () {
for (let i = 0; i < layers.length; i++) {
const result = await connect(layers[i]);
console.log(result, "connected");
}
console.log("All layers are connected");
})();
Upvotes: 1
Views: 656
Reputation: 222989
It is possible to use await
in async
function. And thus, to use it with other statements that are used in async
besides for
, namely do..while
and while
loop statements.
Is there some way to call asynchronous function in NOT for loop (e.g. foreach, map)
This is a different case. Callback-based methods like forEach
have their own functions. It's impossible to use await
inside regular function:
arr.forEach(() => {
await ... // syntax error
});
Using async
function together with await
with forEach
is a common mistake because it results in a promise that is ignored:
arr.forEach(async () => {
await ... // isn't awaited outside function
});
It's acceptable to use async..await
with map
because of the way it works, a promise that is returned from async
is used by map
and mapped to resulting array:
const arrOfPromises = arr.map(async () => {
await ...
});
Promises should be explicitly chained in order to be awaited outside map
function:
await Promise.all(arrOfPromises);
Upvotes: 0
Reputation: 72336
You are looking for Promise.all()
. It gets an array (or other iterable object) of Promise
s and returns a new Promise
that resolves when all the input Promise
s resolve. The input Promise
s are executed in parallel (much better than await
-ing for each Promise
in a loop).
You await
this Promise
.
const layers = ["layer1", "layer2", "layer3"];
async function connect(layer: string): Promise<object> {
return new Promise((resolve, reject) => {
setTimeout(function () {
resolve(layer);
}, 1000);
});
}
await Promise.all(layers.map(connect));
console.log('All layers are connected');
Upvotes: 3
Reputation: 1606
Technically speaking you "can", but you don't want to. If you have a collection of promises you need to resolve, it's best to resolve them with Promise.all()
.
Upvotes: 1