关于事件循环机制,可以参考这篇文章
node 环境中的微任务
这里面补充一个,node 中微任务是有优先级的,常见的微任务有,其中 process.nextTick 的优先级最高,会优先执行,剩下的按照进入微任务队列的顺序,一次执行
- process.nextTick
- 此方法是 node 中将回调函数安排在当前执行栈的尾部,在I/O操作之后、事件循环的阶段之前执行,所以他的优先级最高!!
- promise
- 是 js 的原生对象,他的 .then 和 .catch 中注册的回调函数会被作为微任务。
- 注意 new promise 中的代码会当做同步任务执行,只有 then catch 里面的才是微任务,并且在此之前一定要 resolve 或者 reject 改变promise 的状态,才能执行
- queueMicrotask
- node 中全局作用于中定义的函数,它接受一个函数作为参数,会在微任务队列中添加一个任务。
可以自己看一下下面代码的输出,注意需要在 node 环境下运行
console.log(1)
setTimeout(() => {console.log(2)new Promise((resolve) => {console.log(3)resolve()}).then(() => {console.log(4)})queueMicrotask(() => {console.log(5)})process.nextTick(() => {console.log(6)})console.log(7)}, 10);
process.nextTick(function () { console.log(8) })
new Promise((resolve) => {console.log(9)resolve()
}).then(() => {console.log(10)
})
queueMicrotask(() => {console.log(11)
})
输出结果如下:
浏览器环境中的微任务
浏览器环境中的微任务没有优先级的区别,都是按照进入队列的顺序执行的,浏览器中的微任务主要有:
- promise
- mutationObserver
- 当DOM结构发生变化时,注册的回调函数会以微任务的形式执行。
- queueMicrotask
- 在 window 上的一个全局的方案
- 想不到吧,浏览器也有这个方法,不要以为他是 node 里面才有的
复制下面代码到开发者工具中运行即可查看结果,注意找一个有 a 标签的网站
console.log(1)
new Promise((resolve) => {console.log(2)resolve()
}).then(() => {console.log(3)
})
// 监控一个元素
const node = document.querySelector('a')
const observer = new MutationObserver(() => {console.log(5)
})
observer.observe(node, {attributes: true
})
// 修改元素属性,用于监控
node.style.color = 'red'
queueMicrotask(() => {console.log(4)
})
结果如下,可以发现,这三个微任务是没有特殊的优先级的
加油,一切都是纸老虎,只要学会这点题目,事件循环统统都拿下