资讯专栏INFORMATION COLUMN

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

CoderDock / 946人阅读

摘要:一句话解释在事件循环机制中,有任务两个队列队列和队列。设置任务为目前运行的任务,并执行。应该是考虑到了这一点,至少任务中的任务,是被设置了在一个事件循环中的最大调用次数的,叫。参考材料理解事件循环

在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

事件循环机制详解

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

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

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

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

检查Microtask队列:

1)选择其中最老的任务a,如果任务a不存在,直接结束Microtask队列。
2)设置任务a为“目前运行的任务”,并执行。
3)设置“目前运行的任务”为null,从Microtask队列中移除任务a。
4)选择下一个最老的任务b,跳到步骤2)。
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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91266.html

相关文章

  • JS是单线程,你了解其运行机制吗?

    摘要:的单线程,与它的用途有关。事件循环事件循环是指主线程重复从消息队列中取消息执行的过程。到此为止,就完成了工作线程对主线程的通知,回调函数也就得到了执行。 一. 区分进程和线程 很多新手是区分不清线程和进程的,没有关系。这很正常。先看看下面这个形象的比喻: 进程是一个工厂,工厂有它的独立资源-工厂之间相互独立-线程是工厂中的工人,多个工人协作完成任务-工厂内有一个或多个工人-工人之间共享...

    AlphaGooo 评论0 收藏0
  • 一篇文章教会你Event loop——浏览器和Node

    摘要:如果没到毫秒,那么阶段就会跳过,进入阶段,先执行的回调函数。参考文档什么是浏览器的事件循环不要混淆和浏览器中的定时器详解浏览器和不同的事件循环深入理解事件循环机制篇中的执行机制 最近对Event loop比较感兴趣,所以了解了一下。但是发现整个Event loop尽管有很多篇文章,但是没有一篇可以看完就对它所有内容都了解的文章。大部分的文章都只阐述了浏览器或者Node二者之一,没有对比...

    Leck1e 评论0 收藏0
  • 理解浏览器和node.js中的Event loop事件循环

    摘要:浏览器和中并不一样,浏览器的是在中定义的规范,而中则由库实现。整个的这种运行机制又称为事件循环例子了解浏览器的后,查看下面例子,猜测浏览器是怎么输出的浏览器输出中的在内部有这样一个事件环机制。在启动时会初始化事件环。执行和中到期的。 大家都知道,javascript是一门单线程语言,因此为了实现主线程的不阻塞,Event Loop这样的方案应运而生。 浏览器和node中Event lo...

    iliyaku 评论0 收藏0
  • 浏览器渲染机制

    摘要:浏览器渲染进程浏览器内核进程,内部是多线程的默认每个页面一个进程,互不影响。事件触发线程归属于浏览器而不是引擎,用来控制事件循环可以理解成引擎自己都忙不过来,需要浏览器另开线程协助。 线程和进程 进程和线程的概念可以这样理解: 进程是一个工厂,工厂有它的独立资源--工厂之间相互独立--线程是工厂中的工人,多个工人协作完成任务--工厂内有一个或多个工人--工人之间共享空间 工厂有多个工人...

    appetizerio 评论0 收藏0
  • 浏览器渲染机制

    摘要:浏览器渲染进程浏览器内核进程,内部是多线程的默认每个页面一个进程,互不影响。事件触发线程归属于浏览器而不是引擎,用来控制事件循环可以理解成引擎自己都忙不过来,需要浏览器另开线程协助。 线程和进程 进程和线程的概念可以这样理解: 进程是一个工厂,工厂有它的独立资源--工厂之间相互独立--线程是工厂中的工人,多个工人协作完成任务--工厂内有一个或多个工人--工人之间共享空间 工厂有多个工人...

    lncwwn 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<