js事件循环中的异步队列有两种:macro(宏任务)队列和 micro(微任务)队列。
常见的 macro-task 比如: setTimeout、setInterval、 setImmediate、script(整体代码)、 I/O 操作、UI 渲染等。
常见的 micro-task 比如: process.nextTick、Promise、MutationObserver 等。
循环过程
我们先看一个完整的 Event Loop 过程。
- 初始状态:micro 队列空,macro 队列里有且只有一个 script 脚本(整体代码为宏任务);
- 执行script代码,创建的宏任务推到宏任务调用栈中,创建的微任务推到微任务调用栈中;【宏任务阶段】
- 执行微任务,调出当前微任务栈的所有微任务,一次执行,其中如果有宏任务推到宏任务栈中【微任务阶段】
- 执行宏任务,调出当前宏任务栈中的第一个宏任务,其中创建的微任务推到微任务栈中【宏任务阶段】
- 如果代码未结束,循环执行3,4步骤
从上我们可以总结两个规律
- 宏任务和微任务阶段是轮番交替进行的
- 每个宏任务阶段只执行当前宏任务栈中的第一个任务,执行完就切换到微任务阶段,而微任务阶段却是要执行当前微任务栈的所有微任务,微任务阶段才结束
如果不理解两个规律那么我们就来试着做一道promise的面试题来加深一下
console.log('sync');
setTimeout(function () {
console.log('setTimeout')
}, 0);
var promise = new Promise(function (resolve, reject) {
console.log('promise');
setTimeout(function() {
promise.then(function(){
console.log('promise-setTimeout-then')
})
console.log('promise-setTimeout')
}, 0);
resolve();
});
promise.then(function() {
setTimeout(function() {
promise.then(function(){
console.log('then-setTimeout-then')
})
console.log('then-setTimeout')
}, 0);
console.log('then');
promise.then(function(){
console.log('then-than')
})
})
我们先分析一下这段代码中有几个宏任务微任务阶段,我们假装自己是电脑执行一下代码
首先页面加载后同步代码会被推到宏任务中,故第一步是执行script的【宏任务阶段】,我们将宏任务和微任务将分别用两个数组来表示
//宏任务
macro = ["script同步代码"]
//微任务
micro = []
script代码开始执行
注://注释部分表示不在当前阶段执行的代码
阶段1【宏任务阶段】
执行第一个宏任务 script同步代码,执行后删除当前宏任务
console.log('sync');
/**监测到settimeout,创建宏任务,并push到宏任务栈中 宏任务+1 macro = ['setTimeout'] **/
//setTimeout(function () {
// console.log('setTimeout')
//}, 0);
var promise = new Promise(function (resolve, reject) {
console.log('promise');
/** 宏任务+1

本文深入解析JavaScript事件循环机制,区分宏任务与微任务的区别及执行流程。通过具体示例,详细阐述宏任务与微任务如何轮番执行,帮助读者更好地理解和掌握JavaScript异步编程。
最低0.47元/天 解锁文章
2万+





