vich
vich

Reputation: 292

Is it possible to use await in other then for() loop?

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

Answers (3)

Estus Flask
Estus Flask

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

axiac
axiac

Reputation: 72336

You are looking for Promise.all(). It gets an array (or other iterable object) of Promises and returns a new Promise that resolves when all the input Promises resolve. The input Promises 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

dvsoukup
dvsoukup

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

Related Questions