Event Loop、macrotask、micritask 的结论和参考
Event Loop
JavaScript 是单线程的语言,为了处理一些耗时的任务,会将任务分布到主线程和任务队列中。
一旦主线程的所有任务执行完毕,就会读取任务队列里面的任务。
macrotask vs microtask
任务队列里的任务又分 macrotask 和 microtask,并且单独维护。
如果你需要在同步中进行异步任务,那么使用 microtask;否则就使用 macrotask。
- macrotasks: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering
- microtasks: process.nextTick, Promises, Object.observe, MutationObserver
执行顺序
- 执行主线程的任务
- 遇到一些非立即执行的任务,分别放到 macrotask 和 microtask 队列中。
- 立即执行 microtask 中所有的任务。
- 开始执行 macrotask 中的第一个任务,并且可能继续产生新的任务。
- 如果 4 产生了 microtask,会继续执行 3。
- 接着 4 开始执行下一个 macrotask 任务。
执行示例
下面提供了 4 个例子,可以先自己推算下对不对,其中最后一个是需要在 node.js 环境中执行。
console.log(1);
setTimeout(() => {
console.log(2);
})
setTimeout(() => {
console.log(3);
})
new Promise((resolve)=>{
console.log(4);
resolve();
}).then(()=>{
console.log(5);
})
// 1 4 5 2 3
console.log(1);
setTimeout(() => {
console.log(2);
})
setTimeout(() => {
console.log(3);
})
new Promise((resolve)=>{
console.log(4);
resolve();
}).then(()=>{
console.log(5);
new Promise((resolve) => {
console.log(6);
resolve();
}).then(() => {
console.log(7);
})
})
// 1 4 5 6 7 2 3
console.log(1);
****
setTimeout(() => {
console.log(2);
new Promise((resolve) => {
console.log(6);
resolve();
}).then(() => {
console.log(7);
})
})
setTimeout(() => {
console.log(3);
})
new Promise((resolve)=>{
console.log(4);
resolve();
}).then(()=>{
console.log(5);
})
// 1 4 5 2 6 7 3
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')
})
})
process.nextTick(function() {
console.log('6');
})
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
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
参考资料
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: JavaScript 面试题合集
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论