Skip to main content

Command Palette

Search for a command to run...

Javascript: How to use await in for loops

Published
2 min read

In Javascript we get the benefit of working with async with its API being fairly simple, allowing the slower task to run in parallel instead of in a series. However, if you are newish to programming, there are some easy traps to fall into.

function mockAPICall() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(Math.random());
    }, 1000);
  });
}

The following will work and you might not realise you have heavily reduced performance, it's good to keep an eye out for the following:

// Bad
async function asyncLoopsBad() {
  let finalResult = 0;
  for (let i = 0; i < 10; i++) {
    finalResult += await mockAPICall(); //notice the await in the loop
  }
  return finalResult
}

As you can see, we perform a loop 10 times, and each time we start the loop, we make a request and wait for that to finish before moving to the next iteration of the loop. The following example provides a simple solution to this performance bottleneck:


// Good
async function asyncLoopsGood() {
  const promises = [];
  for (let i = 0; i < 10; i++) {
    promises.push(mockAPICall());
  }
  const results = await Promise.all(promises);
  return results.reduce((result, total)=>total+=result)
}

In asyncLoopsGood, we can kick off the request and proceed to the next request in the loop without waiting, and we use a Promise.all() to ensure all the requests are complete before moving to the next step such as returning the results.

let start1 = Date.now();
asyncLoopsBad().then((result) => {
  console.log("asyncLoopsBad() took", Date.now() - start1, "ms", "result", result);
});
let start2 = Date.now();
asyncLoopsGood().then((result) => {
  console.log("result", result, "asyncLoopsGood() took", Date.now() - start2, "ms", "result", result);
});

// "result" 10 "asyncLoopsGood() took" 1011 "ms" "result" 10
// "result" 10 "asyncLoopsBad() took" 10010 "ms" "result" 10

In this simple comparison, you can see there is a 10x improvement by using the correct control flow for the async loop, if you spot this in a code base, you can get some easy performance gains.