Why should we store Promise objects in variables?

Viewed 303

Let us suppose that we've got a function that resolves a promise like below:

function timeoutPromise(interval) {
  return new Promise((resolve, reject) => {
    setTimeout(function(){
      resolve("done");
    }, interval);
  });
};

and let us suppose that we call that function inside an asynchronous function in two different ways;

slow synchornous way:

async function timeTest() {
  await timeoutPromise(3000);
  await timeoutPromise(3000);
  await timeoutPromise(3000);
}

Here we simply await all three timeoutPromise() calls directly. Each subsequent one is forced to wait until the last one finished, this will result in total run time of around 9 seconds.

and fast asynchronous way:

async function timeTest() {
  const timeoutPromise1 = timeoutPromise(3000);
  const timeoutPromise2 = timeoutPromise(3000);
  const timeoutPromise3 = timeoutPromise(3000);

  await timeoutPromise1;
  await timeoutPromise2;
  await timeoutPromise3;
}

Here we store the three Promise objects in variables, which has the effect of setting off their associated processes all running simultaneously. This will result in total run time of around 3 seconds.

But the question is, why storing Promise objects in variables has the effect setting off their associated processs running simultaneously? what happens under the hood?

1 Answers
await foo();
await bar();

will only call bar (and thus create the second promise) after the promise returned by foo is resolved.

var x = foo();
var y = bar();
await x;

calls bar (and thus creating the second promise) before the promise returned by foo is resolved.

That's what makes the promises "concurrent". If you add console.log in various places you will see the difference in execution:

function timeoutPromise(name, interval) {
  return new Promise((resolve, reject) => {
    console.log(`Promise ${name} created.`);
    setTimeout(function(){
      console.log(`Promise ${name} resolved.`);
      resolve("done");
    }, interval);
  });
};

async function timeTest1() {
  console.log('test 1');
  await timeoutPromise(1, 3000);
  console.log('between promise 1 and 2');
  await timeoutPromise(2, 3000);
}

async function timeTest2() {
  console.log('test 2');
  const timeoutPromise1 = timeoutPromise(1, 3000);
  console.log('between promise 1 and 2');
  const timeoutPromise2 = timeoutPromise(2, 3000);

  await timeoutPromise1;
  console.log('between promise 1 and 2 with await');
  await timeoutPromise2;
}

timeTest1().then(timeTest2);

Related