Search code examples
javascriptpromisees6-promiseevent-loopjob-queue

What is the difference between "event loop queue" and "job queue"?


I can not understand how the following code run. Why "1" is after "b" but "h" is after "3"?

Shouldn’t the order be a, b, 1, 2, h, 3? Some articles said that the difference between "event loop queue" and "job queue" leads to the following output. But how? I have read the specification of ECMAScript 2015 - 8.4 Jobs and Job Queues, wanting to know how Promise'job works, but it makes me more confused. How can I fix this?

var promise = new Promise(function(resolve, reject) {resolve(1)});
promise.then(function(resolve) {console.log(1)});
console.log('a');
promise.then(function(resolve) {console.log(2);});
setTimeout(function() {console.log('h')}, 0);
promise.then(function(resolve) {console.log(3)});
console.log('b');

// a
// b
// 1
// 2
// 3
// h

I know Promise is asynchronous, but the callback of the setTimeout(..) asynchronous operation is always after Promise's asynchronous operation. Why?


Solution

  • Why "1" is after "b"?

    The promise specification states that all promise .then() handlers must be called asynchronously after the call stack has emptied. Thus, both a and b, which are executed synchronously on the call stack will execute before any .then() handlers so 1 will always be after a and b.

    Some interesting reading:

    1. Tasks, microtasks, queues and schedules.
    2. What is the order of execution in JavaScript promises?
    3. Writing a JavaScript framework - Execution timing, beyond setTimeout.

    There's some good advice here in the thread "Promises wiggle their way between nextTick and setImmediate":

    I would not recommend relying on the exact execution order of non-chained events. If you want to control the execution order - rearrange the callbacks in a way so that the one that you want to be executed later depends on the one that you want to be executed earlier, or implement a queue (that does the same behind the hood).

    In other words, if you depend upon a particular ordering of asynchronous events, then you should actually chain them rather than relying on unspecified scheduling in the implementation.