这是我参与「第五届青训营 」伴学笔记创作活动的第 10 天
在上一篇笔记中介绍了JS中的同步任务和异步任务,今天要介绍里面更重要的内容--宏任务和微任务。
一、同步任务和异步任务
1、同步任务:
同步任务是指在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务,当我们打开网站时,网站的渲染过程,比如元素的渲染,其实就是一个同步任务。
2、异步任务:
在JS的设计中有一个任务队列,这是不同于主线程的队列。在遇到异步任务时,会放置在任务队列中,等待同步任务执行完之后才会放入主线程当中。
二、宏任务和微任务
异步任务细分为宏任务和微任务。
1、宏任务
宏任务主要有以下几种:
- 主代码块
- setTimeout
- setInterval
- DOM事件
- AJAX请求
- IO
- UI渲染
2、微任务
微任务主要有以下几种:
- Promise.then finally catch
- process.nextTick
- async/await
- MutationObserver
3、执行顺序
其实宏任务和微任务是这样的,在代码执行时,遇到微任务会放入微任务队列中。在每一次完成宏任务之后,都会将微任务队列中的任务清空。不过实际上微任务优先度应该是比宏任务高的,只不过在第一次执行时微任务队列中没任何微任务,所以会先执行主代码块并将里面的微任务提取出来,再去执行微任务。
下面是一个例子:
setTimeout(function() {
console.log('setTimeout');
})
new Promise(function(resolve) {
console.log('promise1');
}).then(function() {
console.log('then1');
})
new Promise(function(resolve) {
console.log('promise2');
}).then(function() {
console.log('then2');
})
console.log('console');
结合之前的同步与异步任务来看,代码的执行结果如下:
promise1
promise2
console
then1
then2
setTimeout
执行逻辑如下:
- 首先从上往下将主代码块作为宏任务执行
- 先遇到setTimeout事件,将其放入宏任务队列当中
- 然后进入第一个promise,先输出promise1(同步任务),然后将then1放入微任务队列中
- 在然后进入第二个promise,同理先输出promise2(同步任务),然后将then2放入微队列之中
- 遇到console,输出console(同步任务)
- 以上为第一个宏任务,然后寻找微任务执行,按照顺序先输出then1,再输出then2
- 微任务队列清空后,执行下一个宏任务,这里即为setTimeout事件,输出setTimeout
- 执行完毕
以上即为宏任务和微任务的例子和说明。