javascriptasynchronouspromisetask-queueorder-of-execution

Execution order question when processing JavaScript asynchronous functions (promise)


I'd like to know the order in which the JavaScript code below is executed and why. In particular, I would like to learn more about the contents of the code that goes into the microtask queue, focusing on step-by-step

var promise = Promise.resolve();

promise = promise.then(function(rtnVal) {
  console.log('1');
  var promise2 = Promise.resolve();
  promise2 = promise2.then(function(rtnVal) {
    console.log('2');
  });
  promise2 = promise2.then(function(rtnVal) {
    console.log('3');
  });
  console.log('4');
});

promise = promise.then(function(rtnVal) {
  console.log('5');
  var promise2 = Promise.resolve();
  promise2 = promise2.then(function(rtnVal) {
    console.log('6');
  });
  promise2 = promise2.then(function(rtnVal) {
    console.log('7');
  });
  console.log('8');
});

console.log('9');

Here's what I did: 9,1,4,2,5,8,3,6,7 ->I'm wondering why it runs in this order`


Solution

  • Some things to be aware of:

    To ease the analysis, I modified your script to give a name to each promise (a to i) and to each callback function (a_then, ...), but the logic and output remains the same:

    var a = Promise.resolve();
    
    var b = a.then(function a_then() {
      console.log(1);
      var c = Promise.resolve();
      var d = c.then(function c_then() {
        console.log(2);
      });
      var e = d.then(function d_then() {
        console.log(3);
      });
      console.log(4);
    });
    
    var f = b.then(function b_then() {
      console.log(5);
      var g = Promise.resolve();
      var h = g.then(function g_then() {
        console.log(6);
      });
      var i = h.then(function h_then() {
        console.log(7);
      });
      console.log(8);
    });
    
    console.log(9); 

    Here is a sequence of events that happen during the execution of that code.

    Here we go:

    Task Action a b c d e f g h i PromiseJob queue
    Script a = Promise.resolve() F - - - - - - - -
    Script b = a.then(a_then) F ? - - - - - - - a_then
    Script f = b.then(b_then) F ? - - - ? - - - a_then
    Script console.log(9) F ? - - - ? - - - a_then
    Host dequeue a_then F ? - - - ? - - -
    a_then console.log(1) F ? - - - ? - - -
    a_then c = Promise.resolve() F ? F - - ? - - -
    a_then d = c.then(c_then) F ? F ? - ? - - - c_then
    a_then e = d.then(d_then) F ? F ? ? ? - - - c_then
    a_then console.log(4) F ? F ? ? ? - - - c_then
    a_then return resolves b F F F ? ? ? - - - c_then, b_then
    Host dequeue c_then F F F ? ? ? - - - b_then
    c_then console.log(2) F F F ? ? ? - - - b_then
    c_then return resolves d F F F F ? ? - - - b_then, d_then
    Host dequeue b_then F F F F ? ? - - - d_then
    b_then console.log(5) F F F F ? ? - - - d_then
    b_then g = Promise.resolve() F F F F ? ? F - - d_then
    b_then h = g.then(g_then) F F F F ? ? F ? - d_then, g_then
    b_then i = h.then(h_then) F F F F ? ? F ? ? d_then, g_then
    b_then console.log(8) F F F F ? ? F ? ? d_then, g_then
    b_then return resolves f F F F F ? F F ? ? d_then, g_then
    Host dequeue d_then F F F F ? F F ? ? g_then
    d_then console.log(3) F F F F ? F F ? ? g_then
    d_then return resolves e F F F F F F F ? ? g_then
    Host dequeue g_then F F F F F F F ? ?
    g_then console.log(6) F F F F F F F ? ?
    g_then return resolves h F F F F F F F F ? h.then
    Host dequeue h_then F F F F F F F F ?
    h_then console.log(7) F F F F F F F F ?
    h_then return resolves i F F F F F F F F F
    Host queue is empty F F F F F F F F F