最近在学习浏览器的事件循环机制,整理了一些笔记,如有错误敬请指正。
事件队列中主要包含宏任务与微任务队列:
1、宏任务(macrotask):setTimeout、setInterval、setImmediate、ajax、DOM监听、UI Rendering等
2、微任务(microtask):promise.then/catch的回调、queueMicrotask()、Mutation Observer API等
另外,async与await可以认为是promise的语法糖
- 可以将await关键字后面执行的代码,看做是包裹在(resolve. reject) => {函数执行}中的代码
- await的下一条语句,可以看做是then(res => {函数执行})中的代码,即进入微任务队列
async function async1() {
console.log('1');
await async2();
console.log('3');
}
async function async2() {
console.log('2');
}
console.log('script start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
async1();
new Promise((resolve) => {
console.log('promise1');
resolve();
}).then(() => {
console.log('promise2');
});
console.log('script end');
// 执行顺序
// script:script start、1、2、promise1、script end
// 微任务:3、promise2
// 宏任务:setTimeout
// 执行顺序依次为script、微任务、宏任务
代码执行遵循以下规则:
1、script中的代码优先执行
2、在执行任何一个宏任务之前,必须保证微任务队列是空的,否则就优先执行微任务队列中的任务
3、计时函数如setTimeout等,需要计时结束才会加入至队列中