Js understand the operational mechanism - the micro and macro task task

Thoughts from a face questions.

setTimeout(function() {
  console.log(4);
}, 0);

new Promise(function(reslove) {
  console.log(1);
  reslove();
}).then(function(data) {
  console.log(3);
});

console.log(2);
复制代码

Outputs: 1,2,3,4. Let's think about why.

Browser event loop eventLoop, divided into synchronous and asynchronous execution stack queue, will first perform synchronization tasks, task synchronization after executing the asynchronous tasks will be taken from the asynchronous queue to get synchronized execution execution stack.

When taking asynchronous queue, there will be a distinction between task is to distinguish between micro and macro tasks.

  • microtask: micro-task, a high priority, and can jump the queue, not define executed first. Including: promise of then, observer, MutationObserver, setImmediate
  • macrotask: macro task, low priority, first define the first execution. Include: ajax, setTimeout, setInterval, event binding, postMessage, MessageChannel (used for message communication)

Because higher priority micro task, so the task will first micro asynchronous tasks taken out for execution, when the task micro tasks were completed, the macro will be taken out tasks in the task execution.

This time we look at the above problems, promise is synchronized task, promise .then the task is asynchronous, and micro-tasks. Use setTimeout macro task, even if the delay is 0, it is also a macro task.

Therefore, the above execution order is added to the first setTimeout macrotask asynchronous queue pool, and then perform the promise console.log(1), the promise then added .then micro asynchronous queue task pool, and then perform the synchronization task console.log(2), when the task synchronization after execution, to micro-task task execution console.log(3), micro-macro task execution take after completing the task, execution console.log(4). So the order is: 1,2,3,4.

Extended:

These questions some pavement reconstruction:

setTimeout(function() {
  console.log(4);
}, 0);

new Promise(function(reslove) {
  console.log(1);
  setTimeout(function() {
    reslove('done');
  }, 0);
  reslove('first');
}).then(function(data) {
  console.log(data);
});

console.log(2);
复制代码

This time will output: 1,2, first, 4, no output done, some people might think, should be output 1,2, first, 4, done, this time you have to know when to use reslove, promise of from pedding state becomes a resolve, after the promise of status changes can not change it , so reslove('done')it will not be executed.

When we reslove('done')change the console.log('done')time, he would output 1,2, first, 4, done up.

Do a more complex changes:

setTimeout(function() {
  console.log(1);
}, 0);

new Promise(function(reslove) {
  console.log(2);
  reslove('p1');
  new Promise(function(reslove) {
    console.log(3);
    setTimeout(function() {
      reslove('setTimeout2');
      console.log(4);
    }, 0);
    reslove('p2');
  }).then(function(data) {
    console.log(data);
  });
  setTimeout(function() {
    reslove('setTimeout1');
    console.log(5);
  }, 0);
}).then(function(data) {
  console.log(data);
});

console.log(6);
复制代码

The resulting output is: 2,3,6, p2, p1,1,4,5.

Perform a synchronization of tasks, new Promise of tasks are synchronized, so the first output 2,3,6, and then perform the task of micro, micro-tasks can jump the queue, so p1 is not to define the first execution, but first p2 execution and implementation of p1, when the micro-tasks are executed, perform tasks macro, the macro task sequentially outputs 1,4,5, promise the state can not change, so setTimeout1 and setTimeout2 not output.

Guess you like

Origin blog.csdn.net/weixin_33724059/article/details/91373132