乐趣区

深入浅出任务队列机制,非常浅

前言
众所周知,js 是单线程的,就像我们不能一边刷牙一边洗脸(或许有些大佬真的可以),那么单线程如何才能规划调度好要做的任务呢?这个时候就要介绍一下这个任务机制了~
任务种类
宏任务

微任务

注意:浏览器环境和 node 环境是不一样的,本文只讨论浏览器环境
规则
执行一个宏任务 (先执行同步代码)–> 执行所有微任务 –>UI render–> 执行下一个宏任务 –> 执行所有微任务 –>UI render–>
根据 HTML Standard,一轮事件循环执行结束之后,下轮事件循环执行之前开始进行 UI render。即:macro-task 任务执行完毕,接着执行完所有的 micro-task 任务后,此时本轮循环结束,开始执行 UI render。UI render 完毕之后接着下一轮循环。但是 UI render 不一定会执行,因为需要考虑 ui 渲染消耗的性能已经有没有 ui 变动
需要注意的是,微任务是有优先级的,就如同上面的表格从上往下一样,nextTick>Promise>MutationObserver.
那么宏任务有没有优先级呢??
大部分浏览器会把 DOM 事件回调优先处理 因为要提升用户体验 给用户反馈,其次是 network IO 操作的回调,再然后是 UIrender,之后的顺序就难以捉摸了,其实不同浏览器的表现也不太一样,这里不做过多讨论。

来道经典题目
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’ 先走完所有同步代码 - 到 promise 微任务 - 宏任务 setTimeout

退出移动版