Zebra
Zebra

Reputation: 189

Async functions works weird with Promises

I am trying to understand the mechanism of async functions. I found some code on MDN docs MDN docs, made some modifications and... cannot fully understand how it works.

var resolveAfter2Seconds = function() {
  console.log("starting slow promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(20);
      console.log("slow promise is done");
    }, 6000);
  });
};


var resolveAfter1Second = function() {
  console.log("starting fast promise");
  return new Promise(resolve => {
    setTimeout(function() {
      resolve(10);
      console.log("fast promise is done");
    }, 4000);
  });
};


var sequentialStart = async function() {
  console.log('==SEQUENTIAL START==');

  const slow = await resolveAfter2Seconds();
  const fast = await resolveAfter1Second();

  console.log(fast);
  console.log('why?');
  console.log(slow);
}


sequentialStart();

For now I know that if we run this code we will immediately receive '==SEQUENTIAL START==' on the console, then "starting slow promise" then we have a Promise with setTimeout which indicates that 'slow promise is done' will appear after 6 seconds and the resolve(20) callback will be kept in api container since execution stack will be empty.JS gives us 'starting fast promise' and after four seconds we get 'fast promise is done' and then immediately 10, 'why?', 20.

I do not understand: what happens in the background exactly - I know that resolve(20) is kept in api container and the rest of the code are executed, then resolve(10) is also kept in api container and when the execution stack is empty they are returned as the results of resolving their Promises.

But:

  1. What with the timer? 10,why,20 appears long after their timeout passes - resolve 20 appears on the screen long after 6 seconds.

  2. What with order? It seems like they (resolve20 and resolve 10) are ready to be executed and kept in memory until I use them - print them in console in this case? TIME APPEARING and ORDER

I am very determined to understand it correctly.

Upvotes: 0

Views: 68

Answers (1)

Lennholm
Lennholm

Reputation: 7460

Perhaps this will help clear things up. Async-await is just syntactic sugar, so your sequentialStart function is the exact same thing as:

var sequentialStart = function() {
  console.log('==SEQUENTIAL START==');

  resolveAfter2Seconds().then(function(slow) {

    resolveAfter1Second().then(function(fast) {

      console.log(fast);
      console.log('why?');
      console.log(slow);
    });
  });
}

I know that resolve(20) is kept in api container and the rest of the code are executed, then resolve(10) is also kept in api container and when the execution stack is empty they are returned as the results of resolving their Promises

That's not what's happening when using async-await, what your code is doing is the following in this specific order:

  1. Call resolveAfter2Seconds()
  2. await it to resolve and then assign the resolved value to the constant slow
  3. Call resolveAfter1Second()
  4. await it to resolve and then assign the resolved value to the constant fast
  5. Call console.log(fast), then console.log('why?'), then console.log(slow)

It seems like you're expecting the promises to resolve in parallel, as they would if you weren't using async-await but the whole purpose of async-await is to be able to write code with promises as if it was synchronous (i.e. blocking) code without creating a nested mess of then callbacks.

Upvotes: 1

Related Questions