Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to run async operations one after another

Short answer

await inside a for...of loop waits for each operation before starting the next one:

const delay = (ms, value) => new Promise((resolve) => setTimeout(() => resolve(value), ms));
 
for (const file of ['a.txt', 'b.txt', 'c.txt']) {
  const result = await delay(100, `uploaded ${file}`);
  console.log(result);
}

Output:

uploaded a.txt
uploaded b.txt
uploaded c.txt

Each step uses the previous result

When steps depend on each other, just write them one after another:

const getUser = async (id) => ({ id, name: 'Anna' });
const getOrders = async (user) => [`order of ${user.name}`];
 
const user = await getUser(1);
const orders = await getOrders(user);
 
console.log(orders[0]);

Output:

order of Anna

Collecting results

Push each result into an array:

const double = async (n) => n * 2;
const results = [];
 
for (const n of [1, 2, 3]) {
  results.push(await double(n));
}
 
console.log(results.join(', '));

Output:

2, 4, 6

Common mistake

forEach() does not wait for async functions. The code after it runs before the steps finish:

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
 
[1, 2].forEach(async (n) => {
  await delay(100);
  console.log('step', n);
});
console.log('done?');

Output:

done?
step 1
step 2

Functions used in this recipe

Thanks for reading!

Donate to the site — we work hard for you.