What is the relationship between event loop and Promise [duplicate]

Each event loop has a microtask queue and a macrotask queue.

A microtask is a task that is originally to be queued on the microtask queue rather than a task queue. Refer to https://www.w3.org/TR/html51/webappapis.html#microtask-queue.

There are two kinds of microtasks:

  • solitary callback microtasks, such as Promise
  • and compound microtasks, such as Object.observe, MutationObserver and process.nextTick in Node.js.

And the macrotask queue mainly contains setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O in Nodejs.

In a event Loop, these two task queues will run in two steps:

  1. First, check whether there is a macrotask (call it X) in old macrotask queue ;
  2. If X exists and it is running, wait for it to go to the next step until it was complete; otherwise, goto the next step immediately;
  3. Second, run all microtasks of the microtask queue;
  4. and when run the microtasks, we can still add some more microtaks into the queue, these tasks will also run.

In your example:

  1. First, your Promise initialize new Promise and resolve are synchronous;
  2. and then synchronously add a setTimeout macroTask into the macrotask queue;
  3. then synchronously add the microtask promise.then(function(){}) to the microtask queue, this task will run immediately, because the Promise initialize and resolve are synchronous, this task run before any macrotask; so, console.log the p1 fulfilled;
  4. then add the second macrotask setTimeout to macrotask queue;
  5. after this event loop ended, run the two macrotasks;

for this code:

setTimeout(function(){
  console.log("will be executed at the top of the next Event Loop")
},0)
var p1 = new Promise(function(resolve, reject){
    setTimeout(function(){resolve(1)},0)
});
setTimeout(function(){
    console.log("will be executed at the bottom of the next Event Loop")
},0)
for (var i = 0; i < 100; i++) {
    (function(j){
        p1.then(function(value){
           console.log("promise then - " + j)
        });
    })(i)
}

the output order:

will be executed at the top of the next Event Loop
promise then - 0
promise then - 1
promise then - 2
...
promise then - 99
will be executed at the bottom of the next Event Loop
  1. First add three macrotask setTimeout to macrotask queue, and a microtask promise.then() to the microtask queue;
  2. run a macrotask;
  3. If condition true run all microtasks, but it’s false, so go to the next step;
  4. run the second macrotask;
  5. check whether the promise resolved or not, the condition is true, then run all microtasks;
  6. go on to run other macrotasks;

Leave a Comment