Search code examples
javascriptecmascript-6async-awaites6-promise

What makes `async/await` statements run sequentially vs in parallel in ES6?


I have already gone through the thread Any difference between await Promise.all() and multiple await?, so I am clear about Promise.all and multiple awaits.

Still, I am not very clear about the below 2 scenarios.

In Case 1 why does it execute sequentially (takes 10s) whereas in Case 2 it executes in parallel (takes 4s)?

Case 1:

function promiseWait(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(true);
    }, time);
  });
}

async function test1() {
  var t0 = performance.now()

  var a = await promiseWait(1000)
  var b = await promiseWait(2000)
  var c = await promiseWait(3000)
  var d = await promiseWait(4000)

  var t1 = performance.now()
  console.log("Call to doSomething took " + (t1 - t0) + " milliseconds."); //takes 10secs
  
}
test1()

Case 2:

function promiseWait(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(true);
    }, time);
  });
}

async function test2() {
  var t0 = performance.now()

  const p1 = promiseWait(1000);
  const p2 = promiseWait(2000);
  const p3 = promiseWait(3000);
  const p4 = promiseWait(4000);

  const a = await p1;
  const b = await p2;
  const c = await p3;
  const d = await p4;

  var t1 = performance.now()
  console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")
}

test2()


Solution

  • In the first case because of the await before each call to the promiseWait, to even start executing the next call to the promiseWait it needs to wait until the first call to the promiseWait is finished completely. So you see sequential execution.

    In the second case you have already invoked all the promiseWait functions before you start awaiting them. So the promiseWait has already started executing, then you are awaiting the results one after another.

    Implementation wise in the first scenario, the next call to the setTimeout has to wait until the first setTimeout expires. So the second, third and the fourth timers need to wait until the first timer expires and resolves the promise in order to be scheduled.

    In the seconds case you schedule the setTimeout calls one after the other, so the timers are all already queued. Then you are just awaiting for the timers to expire and resolve your promise one by one.