任务(宏任务):
- 渲染事件(如解析 DOM、计算布局、绘制);
- 用户交互事件(如鼠标点击、页面滚动、放大缩小等);
- JavaScript 脚本执行事件;
- 网络请求完成、文件读写完成事件。
微任务:MutationObserver、Promise
以下内容来自 Google Chrome 的开发者Jake,此文为中文翻译版本。原文地址>>>
当我告诉我的同事Matt Gaunt我正在考虑写一篇关于浏览器事件循环中的微任务排队和执行的文章时,他说:“我跟你说实话,Jake,我不打算读那个。”好吧,反正我已经写好了,所以我们都要坐在这里享受它,好吗?
实际上,如果你更喜欢视频,Philip Roberts在JSConf上就事件循环做了一个很棒的演讲——微任务没有涉及,但它是对其余内容的一个很好的介绍。不管怎样,继续节目…
用这一小段JavaScript:
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
要理解这一点,您需要知道事件循环如何处理任务和微任务。当你第一次遇到它时,这可能会让你头疼。深呼吸……
每个“线程”都有自己的事件循环,因此每个web worker都有自己的事件循环,因此它可以独立执行,而在同一源上的所有窗口都共享一个事件循环,因为它们可以同步通信。事件循环持续运行,执行任何排队的任务。事件循环有多个任务源,这些任务源保证了执行顺序(诸如IndexedDB之类的规范定义了它们自己的),但是浏览器在每次循环中都要选择从哪个源执行任务。这允许浏览器优先选择对性能敏感的任务,比如用户输入。好吧好吧,跟着我……
任务被调度,这样浏览器就可以从内部获取到JavaScript/DOM,并确保这些操作按顺序发生。在任务之间,浏览器可能呈现更新。从鼠标单击到