JS为单线程语言,但是其运行顺序却不是如眼所示的代码顺序,而是有一套规则,这套规则就是任务队列,主要内容是宏任务(macrotask)与微任务(microtask)。
代码一示例:
//主线程直接执行
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')
})
})
输出顺序:1 7 6 8 2 4 9 11 3 10 5 12
代码二示例:
process.nextTick(() => console.log('nextTick'));
new Promise(resolve => {
console.log('promise1');
resolve();
})
.then(() => console.log('promise2'))
.then(() => console.log('promise3'));
setImmediate(() => console.log('setImmediate'));
setTimeout(() => console.log('timeout'), 0);
console.log('start');
输出顺序:promise1 start nextTick promise2 promise3 timeout setImmediate
一、宏任务与微任务区别?
宏任务比微任务执行优先级要低,如果有微任务,会首先执行所有的微任务。
宏任务代码包含中主代码块、setTimeout、setInterval、setImmediate,且执行顺序setTimeout>setImmediate;微任务包含process.nextTick、Promise、MutationObserver,且执行优先级process.nextTick > Promise > MutationObserver。
二、setTimeout与console.log(‘1’)同作为宏任务,为什么setTimeout执行结果不紧跟console.log(‘1’)的执行结果?
setTimeout被称为宏任务,是指其内部的回调函数作为宏任务。setTimeout延迟执行,将内部的回调函数作为下一轮的宏任务。Promise被称为微任务,是指调用了.then的回调函数部分为微任务,其Promise主体内的console.log('7')依然为本轮的宏任务。另:process.nextTick的回调函数为微任务。
三、整体流程
在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。<br /> 如下图所示:如setTimeout函数为异步任务,会被加入到EventTable中,当计时结束后,其回调函数①会被加入到EventQueue中;Promise主体的代码会作为同步任务,加入到主线程顺序执行,但其.then回调函数会被加入到EventTable中,当回调函数②被触发,会被加入到EventQueue中。①和②同时在EventQueue中,犹豫②为微任务,所以②会比①优先执行。<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/641699/1575773175718-2c88dca0-ae45-45ea-b2eb-0f50e65d81f7.png#align=left&display=inline&height=310&name=image.png&originHeight=620&originWidth=633&size=195105&status=done&style=none&width=316.5)