理解浏览器事件循环 event loop
浏览器事件循环机制
-
浏览器事件循环机制:js任务分为同步任务和异步任务,同步任务会直接进入 js 主线程执行,形成一个执行栈,当前一个任务执行完,后一个任务才会执行。异步任务不直接进入主线程,它会先在Event Table中注册回调函数,然后进入任务队列中,等执行栈中为空后,任务队列中的函数就会进入主线程中执行。
-
宏任务:script(整体代码),setTimeout,setInterval,ie支持的setImmediate,MessageChannel,
微任务:es6的Promise.then(),process.nextTick,queueMicrotask(),Object.observe(已废弃),MutationObserver(html5新特性) -
执行:先执行同步任务,然后执行微任务队列中的微任务,再执行宏任务,执行宏任务时,如果遇到微任务就会把微任务放入微任务队列中,遇到宏任务就会把宏任务放入宏任务队列中,当执行完这个宏任务后,会立即将微任务队列中的任务执行完,当微任务队列为空后,再执行下一个宏任务,如此往复。
宏任务与微任务执行
相关题目:
//主线程直接执行
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')
})
}, 0)
//微事件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 3 5 9 11 10 12
再试试
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0);
Promise.resolve()
.then(function () {
console.log('promise1');
})
.then(function () {
console.log('promise2');
});
console.log('script end');
// 输出结果是:script start script end promise1 promise2 setTimeout
再做一题
setTimeout(function () {
console.log("set1");
new Promise(function (resolve) {
resolve();
}).then(function () {
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then4");
});
console.log("then2");
});
});
new Promise(function (resolve) {
console.log("pr1");
resolve();
}).then(function () {
console.log("then1");
});
setTimeout(function () {
console.log("set2");
});
console.log(2);
queueMicrotask(() => {
console.log("queueMicrotask1")
});
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then3");
});
// 执行结果: pr1 2 then1 queueMicrotask1 then3 set1 then2 then4 set2
最后一题
async function async1 () {
console.log('async1 start')
await async2();
console.log('async1 end')
}
async function async2 () {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
async1();
new Promise (function (resolve) {
console.log('promise1')
resolve();
}).then (function () {
console.log('promise2')
})
console.log('script end')
// 执行结果:script start async1 start async2 promise1 script end async1 end promise2 setTimeout