iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > html >Node.js中事件循环的概念是什么
  • 872
分享到

Node.js中事件循环的概念是什么

2024-04-02 19:04:59 872人浏览 独家记忆
摘要

这篇文章主要讲解了“node.js中事件循环的概念是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“node.js中事件循环的概念是什么”吧!什么是事件循

这篇文章主要讲解了“node.js中事件循环的概念是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“node.js中事件循环的概念是什么”吧!

Node.js中事件循环的概念是什么

什么是事件循环?

尽管javascript是单线程的,但是事件循环尽可能的使用系统内核允许Node.js执行非阻塞I/O操作 尽管大部分现代内核是多线程的,他们可以在后台处理多线程任务。当一个任务完成时,内核告诉Node.js,然后适当的回调会被加入到循环中执行,这篇文章会进一步详细的介绍这个话题

时间循环解释

当Node.js开始执行时,首先会初始化事件循环,处理提供的输入脚本(或者放入REPL,本文档未涉及)这会执行异步 api调用,调度计时器,或调用 process.nextTick(),然后开始处理事件循环

下图展示了事件循环执行顺序的简化概览

   ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

每一个盒子代表着事件循环的一个阶段

每一个阶段有一个FIFO的队列 callback 执行,然而每一个阶段基于它自己的方式执行,总体来讲,当事件循环进入到一个阶段里,它将执行当前阶段的任何操作,开始执行当前阶段队列中的回调直到队列完全消耗完或者执行到队列的最大数据。当队列消耗完或者达到最大数量,事件循环就会移动到下一个阶段。

阶段概述

  • timers 这个阶段执行 setTimeout() 和 setInterval() 的回调

  • pending callbacks 执行 I/O 回调推迟到下一个循环迭代

  • idle,prepare 仅在内部使用

  • poll 检索新的 I/O 事件;执行 I/O 相关的回调(几乎所有相关的回调,关闭回调,)

  • check setImmediate() 会在此阶段调用

  • close callbacks 关闭回调,例如: Socket.on('close', ...)

在事件循环的每个过程中,Node.js检查是否它正在等待异步的I/O和计时器,如果没有则完全关闭

阶段详情

timer

一个计时器指定一个回调会被执行的临界点,而不是人们想让它执行的时间,计时器会在指定的过去时间之后尽可能早的执行,然而,操作系统调度或者其他回调会让它延迟执行。

从技术角度上讲,poll 阶段决定了回调何时执行

例如,你设置了一个计时器,100 ms之后执行,然而你的脚本异步读取了一个文件花费了 95ms

const fs = require('fs');

function someAsyncOperation(callback) {
  // Assume this takes 95ms to complete
  fs.readFile('/path/to/file', callback);
}

const timeoutScheduled = Date.now();

setTimeout(() => {
  const delay = Date.now() - timeoutScheduled;

  console.log(`${delay}ms have passed since I was scheduled`);
}, 100);

// do someAsyncOperation which takes 95 ms to complete
someAsyncOperation(() => {
  const startCallback = Date.now();

  // do something that will take 10ms...
  while (Date.now() - startCallback < 10) {
    // do nothing
  }
});

当事件循环进入了 poll 阶段,是一个空的队列,(fs.readFile() 还没有完成),因此它会等待剩余的毫秒数直到最快的计时器阈值到达,当95 ms之后,fs.readFile() 完成了读文件并且会花费10 ms完成添加到poll 阶段并且执行完毕,当回调完成,队列中没有回调要执行了,事件循环循环返回到timers 阶段,执行计时器的回调。在这个例子中,你会看到计时器被延迟了105 ms之后执行

为了防止 poll 阶段阻塞事件循环,libuv(实现了事件循环和平台上所有的异步行为的C语言库)在 poll 阶段同样也有一个最大值停止轮训更多事件

pending callbacks

此阶段为某些系统操作(例如 tcp 错误类型)执行回调。 例如,如果 TCP 套接字在尝试连接时收到 ECONNREFUSED,则某些 *nix 系统希望等待报告错误。 这将在挂起的回调阶段排队执行。

poll

poll 阶段有两个主要的功能

  1. 计算 I/O 阻塞的时间

  2. 执行 poll 队列中的事件

当事件循环进入到了poll阶段并且没有计时器,发生以下两种事情

  • 如果 poll 队列中不为空,事件循环会同步地迭代执行每个回调直到执行所有,或者达到系统的的硬限制

  • 如果 poll 队列是空的,以下两种情况会发生

    • 如果是setImmediate的回调,事件循环会结束 poll 阶段并进入到 check 阶段执行回调

    • 如果不是setImmediate,事件循环会等待回调添加到队列中,然后立即执行

一旦 poll 队列是空的,事件循环会检测计时器是否到时间,如果有,事件循环会到达timers 阶段执行计时器回调

check

此阶段允许人们在 poll 阶段完成后立即执行回调。 如果轮询阶段变得空闲并且脚本已使用 setImmediate() 排队,则事件循环可能会继续到 check 阶段而不是等待。

setImmediate() 实际上是一个特殊的计时器,它在事件循环的单独阶段运行。 它使用一个 libuv API 来安排在 poll 阶段完成后执行的回调。

通常,随着代码的执行,事件循环最终会到达 poll 阶段,它将等待传入的连接、请求等。但是,如果使用 setImmediate() 安排了回调并且 poll 阶段变得空闲,它将结束并继续 check 阶段,而不是等待 poll 事件。

close callbacks

如果一个 socket 或者操作突然被关闭(e.g socket.destroy()),close 事件会被发送到这个阶段,否则会通过process.nextTick()发送

setImmediate() VS setTimeout()

setImmediate() 和 setTimeout() 是相似的,但是不同的行为取决于在什么时候被调用

  • setTimmediate() 在 poll 阶段一旦执行完就会执行

  • setTimeout() 在一小段时间过去之后被执行

每个回调执行的顺序依赖他们被调用的上下本环境,如果在同一个模块被同时调用,那么时间会受到进程性能的限制(这也会被运行在这台机器的其他应用所影响)

例如,如果我们不在I/O里边运行下面的脚本,尽管它受进程性能的影响,但是不能够确定这两个计时器的执行顺序:

// timeout_vs_immediate.js
setTimeout(() => {
  console.log('timeout');
}, 0);

setImmediate(() => {
  console.log('immediate');
});
$ node timeout_vs_immediate.js
timeout
immediate

$ node timeout_vs_immediate.js
immediate
timeout

然而,如果你移动到I/O 循环中,immediate 回调总是会先执行

// timeout_vs_immediate.js
const fs = require('fs');

fs.readFile(__filename, () => {
  setTimeout(() => {
    console.log('timeout');
  }, 0);
  setImmediate(() => {
    console.log('immediate');
  });
});
$ node timeout_vs_immediate.js
immediate
timeout

$ node timeout_vs_immediate.js
immediate
timeout

setImmediate 相对于 setTimeout 的优势是 setImmediate 如果在I/O 中总是会优先于任何计时器被先执行,与存在多少计时器无关。

process.nextTick()

尽管 process.nextTick() 是异步API的一部分,但是你可能已经注意到了它没有出现在图表中,这是因为 process.nextTick() 不是事件循环技术的一部分,相反,当前操作执行完毕之后 nextTickQueue 会被执行,无论事件循环的当前阶段如何。 在这里,操作被定义为来自底层 C/C++ 处理程序的转换,并处理需要执行的 JavaScript。 根据图表,你可以在任意阶段调用 process.nextTick(),在事件循环继续执行之前,所有传递给 process.nextTick() 的回调都将被执行,这个会导致一些坏的情况因为它允许你递归调用 process.nextTick() "starve" 你的 I/O ,这会阻止事件循环进入 poll 阶段。

为什么这会被允许

为什么这种情况会被包含在Node.js中?因为Node.js的设计理念是一个API应该总是异步的即使它不必须,看看下面的片段

function apiCall(arg, callback) {
  if (typeof arg !== 'string')
    return process.nextTick(
      callback,
      new TypeError('argument should be string')
    );
}

该片段会进行参数检查,如果不正确,它会将错误传递给回调。 API 最近更新,允许将参数传递给 process.nextTick() 允许它接受在回调之后传递的任何参数作为回调的参数传播,因此您不必嵌套函数。

我们正在做的是将错误传回给用户,但前提是我们允许用户的其余代码执行。 通过使用 process.nextTick(),我们保证 apiCall() 总是在用户代码的其余部分之后和允许事件循环继续之前运行它的回调。 为了实现这一点,允许 JS 调用堆栈展开,然后立即执行提供的回调,这允许人们对 process.nextTick() 进行递归调用,而不会达到 RangeError:从 v8 开始超出最大调用堆栈大小。

感谢各位的阅读,以上就是“Node.js中事件循环的概念是什么”的内容了,经过本文的学习后,相信大家对Node.js中事件循环的概念是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: Node.js中事件循环的概念是什么

本文链接: https://www.lsjlt.com/news/96830.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Node.js中事件循环的概念是什么
    这篇文章主要讲解了“Node.js中事件循环的概念是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Node.js中事件循环的概念是什么”吧!什么是事件循...
    99+
    2022-10-19
  • node.js中的事件循环是什么
    这篇文章主要介绍“node.js中的事件循环是什么”,在日常操作中,相信很多人在node.js中的事件循环是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”node.js中...
    99+
    2022-10-19
  • Node.js事件循环是什么
    本文小编为大家详细介绍“Node.js事件循环是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Node.js事件循环是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是事件循环首先我们需要了解一下最基...
    99+
    2023-07-04
  • Node.js中事件循环的机制是什么
    本篇内容介绍了“Node.js中事件循环的机制是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!先看一个demo:setTimeout((...
    99+
    2023-06-17
  • JavaScript事件流的概念是什么
    这篇文章主要介绍“JavaScript事件流的概念是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript事件流的概念是什么”文章能帮助大家解决问题...
    99+
    2022-10-19
  • Flex事件中的基本概念是什么
    这篇文章主要为大家展示了“Flex事件中的基本概念是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Flex事件中的基本概念是什么”这篇文章吧。Flex简介Flex是响应RIA(富客户网络应用...
    99+
    2023-06-17
  • Node的事件循环是什么
    这篇文章主要介绍“Node的事件循环是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Node的事件循环是什么”文章能帮助大家解决问题。一、什么是事件循环一句话:事件循环是Nodejs处理异步操作...
    99+
    2023-07-05
  • nodejs事件循环是什么
    这篇文章主要讲解了“nodejs事件循环是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“nodejs事件循环是什么”吧!我们都听说过 JavaScript 和 Node.js 是单线程的...
    99+
    2023-07-04
  • Node.js中事件循环的方法
    本文小编为大家详细介绍“Node.js中事件循环的方法”,内容详细,步骤清晰,细节处理妥当,希望这篇“Node.js中事件循环的方法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Node 自身的执行模型——事件循...
    99+
    2023-06-17
  • Node.js中怎么实现事件循环
    这篇文章将为大家详细讲解有关Node.js中怎么实现事件循环,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Node.js 事件循环Node.js 是单进程单...
    99+
    2022-10-19
  • node环境中npm的概念是什么
    这篇文章主要介绍“node环境中npm的概念是什么”,在日常操作中,相信很多人在node环境中npm的概念是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”node环境中n...
    99+
    2022-10-19
  • 什么是​事件循环event loop
    这篇文章给大家介绍什么是事件循环event loop,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。事件循环event loop。一个老生常谈的问题,之所以拿出来说,推荐的原因在于:通过...
    99+
    2022-10-19
  • Node.js中的模块化概念是什么
    这篇文章主要介绍“Node.js中的模块化概念是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Node.js中的模块化概念是什么”文章能帮助大家解决问题。一、模...
    99+
    2022-10-19
  • Node事件循环的流程是什么
    这篇文章主要讲解了“Node事件循环的流程是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Node事件循环的流程是什么”吧!我们都知道目前我们用的应用程...
    99+
    2022-10-19
  • JavaScript事件循环的原理是什么
    今天小编给大家分享一下JavaScript事件循环的原理是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。理解 JavaS...
    99+
    2023-07-04
  • Node.js中事件循环的示例分析
    这篇文章主要介绍Node.js中事件循环的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Node 自身的执行模型——事件循环,正是它使得回调函数十分普遍。在进程启动时,Nod...
    99+
    2022-10-19
  • Node事件循环机制是什么
    这篇文章主要介绍“Node事件循环机制是什么”,在日常操作中,相信很多人在Node事件循环机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node事件循环机制是什么”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-07-05
  • Ubuntu里的密钥环概念是什么
    这篇文章将为大家详细讲解有关Ubuntu里的密钥环概念是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。如果你用过 Ubuntu 或者其他的 Linux 发行版里的自动登录功能, 你可能遇到过这种弹出消...
    99+
    2023-06-16
  • Vue组件的概念是什么
    本篇内容介绍了“Vue组件的概念是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在多次使用到相同的函数和相同的HTML代码时,可以考虑抽...
    99+
    2023-06-20
  • javascript插件的概念是什么
    本篇内容介绍了“javascript插件的概念是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2022-10-19
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作