Event Loop阶段描述图

timers

timer阶段处理setTimeout于setInterval回调,开始处理的时机与poll阶段有关联。

pending callbacks

该阶段执行某些系统操作的回调,比如TCP套接字在连接时收到ECONNREFUSED。

网上有一些将该阶段称为I/O callbacks的文章都是过时错误的,具体可以移步Node.js官方库下面的这个issue: #1118。

idle, prepare

内部使用,忽略。

poll

poll是一个核心阶段,等新I/O事件的触发,以及执行I/O相关回调。Node.js中出现异步的绝大部分情况都是I/O操作,它们的回调基本都在这个阶段被执行。

poll阶段主要做两件事:

  • 计算需要为新的的I/O事件等待多久

当进入poll阶段,如果队列为空且不存在setImmediate与就绪的timer,Node.js会在这里block一定的时间等待新的I/O事件到来,然后立即执行其回调。这种情况具体block等待多久是不具体的,但如果在block一定时间后仍没有新到达的I/O事件,可以肯定循环依旧会进入check阶段或者回到timer阶段。

  • 处理该阶段队列中的事件

当进入poll阶段,如果队列不为空且没有就绪的timer,Node.js会在这里执行队列中的callback直到队列为空或者执行的callback数达到系统设定的某个值。随后Node.js检查是否存在预设的setImmediate,存在话就进入check阶段,否则开始检查timer就绪情况选择回到timer阶段或者进入check阶段。

对于poll阶段,通过阅读官方的文档有些细节也没弄清楚,用伪代码表示出来:

enter pool phase:
if (has timer scheduled) {
  // 官方没有提到这种情况会做什么
}
else {
  if (isEmpty(queue)) {
    if (has(setImmediate)) {
      // 进入check阶段
    }
    else if (!isEmpty(timer)) {
      // 回到timer阶段
    }
    else {
      // 等待新的I/O事件
      // 新的I/O事件触发回调立即执行,执行完成之后的逻辑不清楚
    }
    // 目前看来只有存在setImmediate时才会进入check阶段,这肯定不合理
  }
  if (!isEmpty(queue)) {
    let result = execute(queue);
    if (result === 'queue is empty') {
      // 官方没讲后续逻辑
      // 猜测是回到队列为空的处理逻辑中
    }
    if (result === 'reached hard limit') {
      // 官方没有解释这里的后续逻辑
      // 也许与queue is empty一样对待
    }
  }
}

疑惑重点是从poll阶段出来的时机以及去向不是非常明确,但以我目前的水平和精力只能到此为止。

check

当poll阶段执行完成会进入到check阶段执行,该阶段的执行内容是所有setImmediate回调。

close callbacks

socket的异常关闭,'close'事件的回调会在该阶段执行。

process.nextTick

process.nextTick经常被用来做异步调用,但它并不属于事件循环的内容,process.nextTick中的回调被放在nextTickQueue中等待“当前操作”完成后被立即处理,与事件循环中的阶段没有联系,当前操作的原文定义是:“An operation is defined as a transition from the underlying C/C handler, and handling the JavaScript that needs to be executed.”,指的是在一段Javascript代码执行完切换到C/C 层时会处理nextTickQueue。

文章提到了一个特例是Deduplication,这是Node.js内部一个优化特性,当在timer和check阶段,同时有多个需要执行的回调时,切换只会发生一次,所以nextTick回调执行在这种情况下看似有所延后。

代码示例:

setImmediate(() => {
  console.log('1');
  process.nextTick(() => console.log('2'));
});
setImmediate(() => {
  console.log('3');
  process.nextTick(() => console.log('4'));
});

存在两个setImmediate,进入check阶段后需要在执行所有setImmediate的回调代码后才会产生切换,从而执行nextTick回调,因此上面代码的运行结果是:“1 3 2 4”,除上述场景外,nextTick都会先于setImmediate执行。

总结

因为Node.js的Event Loop我看了有那么2、3回,但经常忘,所以这次记录下来,做个备忘。由于太多知识容易忘记,又发现写文章的一个优点:“帮助记忆便于复习”。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对Devmax的支持。如果你想了解更多相关内容请查看下面相关链接

Node.js Event Loop各阶段讲解的更多相关文章

  1. 详解使用postMessage解决iframe跨域通信问题

    这篇文章主要介绍了详解使用postMessage解决iframe跨域通信问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. HTML5数字输入仅接受整数的实现代码

    这篇文章主要介绍了HTML5数字输入仅接受整数的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码

    这篇文章主要介绍了HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  4. 浅谈html5之sse服务器发送事件EventSource介绍

    本篇文章主要介绍了浅谈html5之sse服务器发送事件EventSource介绍,具有一定的参考价值,有兴趣的可以了解一下

  5. HTML5 拖放(Drag 和 Drop)详解与实例代码

    本篇文章主要介绍了HTML5 拖放(Drag 和 Drop)详解与实例代码,具有一定的参考价值,有兴趣的可以了解一下

  6. HTML中实现音乐或视频自动播放案例详解

    由于期末大作业我想插入一个背景音乐,实现点开网页就会自动播放音频的效果,今天通过本文给大家分享下我基于HTML实现音乐或视频自动播放功能,代码简单易懂,需要的朋友参考下吧

  7. ios – Swift中的非响应流委托

    所以我在Swift中使用套接字并试图将应用程序与我的服务器连接起来.我让应用程序连接到服务器的IP地址,并在服务器上使用netcat进行测试.在执行期间,应用程序的控制台输出显示它已成功连接到服务器.但是,流委托似乎没有响应.当我输入netcat时,app控制台没有打印任何内容.我已经搜索了很长一段时间,发现我的实现与其他实现非常相似.也许我在这里遗漏了一些我看不到的东西.任何想到这个问题的人都将不胜感激!

  8. ios – UIScrollView内容不允许用户交互

    我有一个启用了分页的UIScrollView,如下所示:在UIScrollView中,我添加了几个UIWebViews,并将其启用的交互设置为是这样的.它打破了UIScrollView上的分页和所有触摸.如果我将用户交互设置为NO,则页面有效,但我无法在UIWebView中突出显示文本.我试着像下面那样对UIScrollView进行子类化,但是会出现同样的情况.任何的想法?

  9. ios – 如何知道用户在iPhone中的播放控件上单击快进和快退按钮

    还是有其他方法吗?

  10. ios – 如何在使用隐式动画为CALayer设置动画时继承动画属性

    我试图使用隐式动画在CALayer上设置自定义属性的动画:在-actionForKey:方法我需要返回动画,负责插值.当然,我必须以某种方式告诉动画如何检索动画的其他参数.有关如何实现这一点的任何想法?

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部