事件循环相关描述
- 为什么有事件循环
- 单线程任务类型
- 同步任务:在主线程上排队,直接执行
- 异步任务:不进入主线程,进入任务队列等待执行
- 微任务 (Micro/Job)
- 包含 Promise.then/cath /finally,MutationObserver回调(html5新特性)
- 宏任务 (MacroTask/Task)
- 包含script、setTimeout、setInterval 、setImmediate、I/O操作
- 一个宏任务里的微任务 没执行完的话,不会执行下一个宏任务
事件循环流程图
案例
案例代码
console.log(1);
setTimeout(() => {
console.log(2,);
Promise.resolve().then(() => {
console.log(3,);
});
});
const pA = new Promise((resolve, reject) => {
console.log(4,);
resolve(5);
}).then((data) => {
console.log(5,data,);
setTimeout(() => {
console.log(7,);
}, 0);
return data;
});
pA.then((res) => {
console.log(8, 'res====', res);
});
setTimeout(() => {
console.log(6,);
});
案例解析
- 整个script宏任务作为第一次事件循环 ,
1.1 输出 【1】
1.2 遇到 setTimeout2,放入任务队列第1位;
1.3 遇到同步的4,输出 【4】;4里面立即调用了resolve,将 5/8放到次轮微任务;
1.4 遇到 setTimeout6,放入任务队列第2位;
1.5 第一轮事件循环宏任务结束;
1.6 检查第一轮里面有没有微任务,有1.3的5/8,输出【5/8】,5后面有setTimeout7,放到任务队列第3位
1.7 第一轮事件循环微任务结束,进行下一个事件循环; - 宏任务里面的第一个为 setTimeout2,
2.1 输出【2】,里面立即调用了resolve,将 3放到次轮微任务
2.2 setTimeout2 这个宏任务结束,执行里面的微任务,输出【3】
2.3. 第二轮事件循环微任务结束,进行下一个事件循环; - 宏任务里面的第二个为 setTimeout6,输出【6】,没有微任务,第三轮结束
- 宏任务里面的第三个为 setTimeout7,输出【7】,没有微任务,第四轮结束