JS macro task, micro task

JS macro task, micro task

Introduction : Two categories of asynchronous tasks: macrotask and microtask

Macro task
main thread
setTimeout
setInterval

微任务
process.nextTick
MutationObserver
Promise.then catch finally


When the task is suspended during execution , the JS engine will divide all tasks into these two queues according to their categories. First, take out the first task from the macrotask queue (this queue is also called task queue), and take out the microtask after execution. All tasks in the queue are executed sequentially; then the macrotask task is taken, and the cycle continues until the tasks in the two queues are all taken.

Insert picture description here
Look at an example of the relationship between macro tasks and micro tasks
Insert picture description here
:

setTimeout(() => {
    
    
    //执行后 回调一个宏事件
    console.log('内层宏事件3')
}, 0)
console.log('外层宏事件1');

new Promise((resolve) => {
    
    
    console.log('外层宏事件2');
    resolve()
}).then(() => {
    
    
    console.log('微事件1');
}).then(()=>{
    
    
    console.log('微事件2')
})

Print result:

外层宏事件1
外层宏事件2
微事件1
微事件2
内层宏事件3

Explanation:
• First, the browser executes js to enter the first macro task to enter the main thread, and when it encounters setTimeout, it is distributed to the macro task Event Queue

• Encounter console.log() directly execute output outer macro event 1

• When Promise is encountered, new Promise is directly executed and output outer macro event 2

• The execution of then is distributed to the microtask Event Queue

• The first round of macro task execution is over, and the micro task starts to print "Micro Event 1" "Micro Event 2"

• After the first round of microtasks are executed, execute the second round of macro events, and print the content in setTimeout "Inner macro event 3"

Look at another example

//主线程直接执行
console.log('1');
//丢到宏事件队列中
setTimeout(function() {
    
    
    console.log('2');
    process.nextTick(function() {
    
    
        console.log('3');
    })
    new Promise(function(resolve) {
    
    
        console.log('4');
        resolve();
    }).then(function() {
    
    
        console.log('5')
    })
})
//微事件1
process.nextTick(function() {
    
    
    console.log('6');
})
//主线程直接执行
new Promise(function(resolve) {
    
    
    console.log('7');
    resolve();
}).then(function() {
    
    
    //微事件2
    console.log('8')
})
//丢到宏事件队列中
setTimeout(function() {
    
    
    console.log('9');
    process.nextTick(function() {
    
    
        console.log('10');
    })
    new Promise(function(resolve) {
    
    
        console.log('11');
        resolve();
    }).then(function() {
    
    
        console.log('12')
    })
})

• First, the browser executes js to enter the first macro task into the main thread, and directly print console.log('1')

• When setTimeout is encountered, it is distributed to the macro task Event Queue

• Encounter process.nextTick and throw it into the microtask Event Queue

• When Promise is encountered, the new Promise is directly executed and output console.log('7');

• The execution of then is distributed to the microtask Event Queue

• The first round of macro task execution ends, and micro task printing starts 6,8

• After the first round of microtasks are executed, execute the second round of macro events, and execute setTimeout

• Execute the main thread macro task first, and print '2,4,3,5' while executing the micro task

• When executing the second setTimeout, print '9,11,10,12' in the same way

• The entire code has three event loops, and the complete output is 1, 7, 6, 8, 2, 4, 3, 5, 9, 11, 10, 12.

The above is the data executed in the browser environment. It is only used for the analysis of macro tasks and micro tasks. The order I tested and printed in the node environment is: 1, 7, 6, 8, 2, 4, 9, 11, 3 , 10, 5, 12. The reason for the inconsistency between the execution result of the node environment and the execution result of the browser is that the event loop of the browser is a specification defined in HTML5, while the node is implemented by the libuv library. The libuv library process is roughly divided into 6 stages: timers, I/O callbacks, idle, prepare, poll, check, close callbacks, which are different from the browser's microtask and macrotask.

Reference document
https://juejin.im/post/59e85eebf265da430d571f89
http://www.cnblogs.com/jiasm/p/9482443.html

Guess you like

Origin blog.csdn.net/weixin_39854011/article/details/108382997