Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make async/await loop execute in order

I have a loop that looks like that:

    newThreadIds.map(async function(id) {
      let thread = await API.getThread(id);
      await ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec();
      await Q.delay(1000);
    });

The problem is that each iteration executes asynchronously and I would like there to be a 1 second delay between them. I know how to do it with promises, but it looks ugly and I would prefer to do it with async/await and as little nesting as possible.

like image 290
Victor Marchuk Avatar asked May 16 '26 01:05

Victor Marchuk


2 Answers

The map function doesn't know that its callback is asynchronous and returns a promise. It just runs through the array immediately and creates an array of promises. You would use it like

const promises = newThreadIds.map(async function(id) {
    const thread = await API.getThread(id);
    return ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec();
});
const results = await Promise.all(promises);
await Q.delay(1000);

For sequential execution, you would need to use Bluebird's mapSeries function (or something similar from your respective library) instead, which cares about the promise return values of each iteration.

In pure ES6, you'd have to use an actual loop, whose control flow will respect the await keyword in the loop body:

let results = [];
for (const id of newThreadIds) {
    const thread = await API.getThread(id);
    results.push(await ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec());
    await Q.delay(1000);
}
like image 179
Bergi Avatar answered May 17 '26 15:05

Bergi


I've figured it out:

    for (let id of newThreadIds) {
      let thread = await API.getThread(id);
      await ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec();
      await Q.delay(1000);
    }

It's probably the best way to it with ES2015 and async/await.

like image 33
Victor Marchuk Avatar answered May 17 '26 15:05

Victor Marchuk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!