宿主(浏览器)发起的任务我们可以称之为宏观任务(macrotask);引擎(js)自己也可以发起任务,这个任务就叫做微观任务(microtask)。
一、js宏任务和微任务分别有哪些?
1、js宏任务有:<script>整体代码、setTimeout、setInterval、setImmediate、Ajax、DOM事件。
2、js微任务有:process.nextTick、MutationObserver、Promise.then catch finally、
async/await实际上是promise+generator的语法糖,也就是promise,也就是微观任务。
3、 new Promise(…)是构造函数,是同步代码。
二、js宏任务和微任务谁先执行?
分情况解释宏任务和微任务的执行顺序:
一、同步——>异步——>微任务——>宏任务。JS是单线程,碰见同步执行同步直到执行完毕,遇到异步放到执行队列中去,异步包括宏任务和微任务,在异步中微任务是优于宏任务执行的。
二、<script>整体代码可看作宏任务,还有就是如果宏任务里包括微任务,那就可以看作宏任务的执行顺序先于微任务。
二、js宏任务和微任务实例代码如下:
setTimeout(() => console.log(4))
new Promise(resolve => {
resolve()
console.log(1)
}).then(_ => {
console.log(3)
})
console.log(2)
实例说明:
1、整个这一串代码我们所在的层级我们看做一个任务,其中我们先执行同步代码。第一行的 setTimeout 是异步代码,跳过,来到了 new Promise(…) 这一段代码。
2、前面提到过,这种方式是一个构造函数,是一个同步代码,所以执行同步代码里面的函数,即 console.log(1),接下来是一个 then 的异步,跳过。最后一个是一段同步代码 console.log(2)。所以,这一轮中我们知道打印了1, 2两个值。接下来进入下一步,即之前我们跳过的异步的代码。从上往下,第一个是 setTimeout,还有一个是Promise.then()。
3、setTimeout 是宏任务的异步,Promise.then()是微任务的异步,微任务是优先于宏任务执行的,所以,此时会先跳过 setTimeout 任务,执行两个 Promise.then() 的微任务。所以此时会执行 console.log(3) 函数。最后就只剩下 setTimeout 函数没有执行,所以最后执行 console.log(4)。
4、综上,最后的执行结果是:1, 2, 3, 4
5、解释下:setTimeout就是作为宏任务来存在的,而Promise.then则是具有代表性的微任务