【新手向】Node.js事件循环中的:Macrotask 与 Microtask

发布时间:2019-06-22 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【新手向】Node.js事件循环中的:Macrotask 与 Microtask脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

在Node学习过程中,不可避免的需要对事件循环机制做深入理解,其中Macrotask(大型任务)和Microtask(小型任务)比较令人困惑,在一番google之后,我发现了几篇资料能比较好地解释他们的原理。因此在这里汇总+搬运一下。

一句话解释

在Nodejs事件循环机制中,有任务两个队列:Macrotask队列和Microtask队列。在一个事件循环里,这两个队列会分两步执行,第一步会固定地执行一个(且仅一个)Macrotask任务,第二步会执行整个Microtask队列中的所有任务。并且,在执行Microtask队列任务的时候,也允许加入新的Microtask任务,直到所有Microtask任务全部执行完毕,才会结束循环。

Macrotasks一般包括: setTimeout, setInterval, setImmediate, I/O, UI rendering;
Microtasks一般包括: process.nextTick, Promises, Object.observe, MutationObserver

事件循环机制详解

从一个事件循环开始,到结束会经历以下步骤:

  1. 检查Macrotask队列,选择其中最早加入(即最老的)的任务X,设置为“目前运行的任务”。如果任务X不存在,那么直接跳到步骤4。

  2. 运行任务X,即运行对应的回调函数。

  3. 设置“目前运行的任务”为null,从Macrotask队列中移除任务X。

  4. 检查Microtask队列:

    1)选择其中最老的任务a,如果任务a不存在,直接结束Microtask队列。
    2)设置任务a为“目前运行的任务”,并执行。
    3)设置“目前运行的任务”为null,从Microtask队列中移除任务a。
    4)选择下一个最老的任务b,跳到步骤2)。
    5)直到队列里没有剩余的任务,结束队列。
  5. 跳回步骤1,检查下一个Macrotask任务。

关于事件循环步骤,参考文档中的《理解 Node.js 事件循环》这篇文章讲的非常好也非常详细,强烈推荐想了解的同学一定要看。

如何选用Macrotask或Microtask呢?

可以这样简单理解:如果你想让一个任务立即执行,那么就把它设置为Microtask,除此之外都用Macrotask比较好。因为可以看出,虽然Node是异步非阻塞的,但在一个事件循环中,Microtask的执行方式基本上就是用同步的。

可能存在的问题

相信读到这里你已经意识到,如果一个Microtask队列太长,或者执行过程中不断加入新的Microtask任务,会导致下一个Macrotask任务很久都执行不了。结果就是,你可能会遇到UI一直刷新不了,或者I/O任务一直完成不了。

应该是考虑到了这一点,至少Microtask任务中的process.nextTick任务,是被设置了(在一个事件循环中的)最大调用次数的,叫process.maxTickDepth。默认是1000。一定程度上避免了上述情况。

参考材料

理解 Node.js 事件循环
Difference between microtask and macrotask within an event loop context

脚本宝典总结

以上是脚本宝典为你收集整理的【新手向】Node.js事件循环中的:Macrotask 与 Microtask全部内容,希望文章能够帮你解决【新手向】Node.js事件循环中的:Macrotask 与 Microtask所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: