介绍
JavaScript作为一门单线程的脚本语言,执行时采用事件轮循机制来处理任务。了解事件轮循机制、宏任务和微任务的概念,对于编写高效的JavaScript代码至关重要。本文将深入探讨事件轮循机制,并给出一些实践案例。
事件轮循机制
事件轮循机制主要由两个组成部分:宏任务队列(macro task queue)和微任务队列(micro task queue)。
宏任务包括脚本执行、setTimeout、setInterval等异步任务,它们会被放入宏任务队列中。而微任务包括Promise、MutationObserver等异步任务,它们会被放入微任务队列中。在每次JS主线程执行完一个宏任务后,会先清空当前的微任务队列,然后再执行下一个宏任务。
宏任务和微任务的执行顺序
在常见的浏览器环境中,宏任务和微任务的执行顺序如下:
- 执行一个宏任务。
- 检查并执行所有微任务。
- UI渲染。
- 执行下一个宏任务。
实践案例
案例一:定时器
console.log('1');
setTimeout(function() {
console.log('2');
}, 0);
Promise.resolve().then(function() {
console.log('3');
});
console.log('4');
// 输出:1 4 3 2
解析:首先,会执行同步代码,输出1和4。然后,会将定时器回调函数放入宏任务队列中。接着,执行微任务队列中的Promise回调函数,输出3。最后,在下一轮循环中,执行宏任务队列中的定时器回调函数,输出2。
案例二:MutationObserver
console.log('1');
new MutationObserver(function() {
console.log('2');
}).observe(document.body, {
childList: true
});
document.body.appendChild(document.createElement('div'));
console.log('3');
// 输出:1 3 2
解析:首先,会执行同步代码,输出1。然后,创建MutationObserver实例,并将其放入微任务队列中。接着,执行宏任务队列中的appendChild方法,添加一个新的div元素到DOM树中。最后,在下一轮循环中,执行微任务队列中的MutationObserver回调函数,输出2。
案例三:Promise
console.log('1');
Promise.resolve().then(function() {
console.log('2');
Promise.resolve().then(function() {
console.log('3');
});
});
setTimeout(function() {
console.log('4');
}, 0);
console.log('5');
// 输出:1 5 2 3 4
解析:首先,会执行同步代码,输出1和5。然后,在微任务队列中添加两个Promise回调函数。接着,将定时器回调函数放入宏任务队列中。最后,在下一轮循环中,先执行微任务队列中的第一个Promise回调函数,输出2,然后执行第二个Promise回调函数,输出3。最终,在下一个宏任务中,执行定时器回调函数,输出4。
结论
了解JS事件轮循机制、宏任务和微任务的执行顺序,对于编写出高效、合理的JavaScript代码非常重要。合理地利用宏任务和微任务,可以提高代码性能和用户体验。
希望本文对大家理解事件轮循机制有所帮助,并能应用于实际的开发中。感谢您的阅读!
参考文献:
本文来自极简博客,作者:倾城之泪,转载请注明原文链接:JS事件轮循机制、宏任务、微任务实践