nodejs 事件循环

浏览器的事件循环比较熟悉了,也来了解下 node 的。
参考来源:

https://nodejs.org/en/guides/event-loop-timers-and-nexttick/
https://juejin.cn/post/6844903999506923528

事件循环分为 6 个阶段,图中每个框都是一个阶段,每个阶段都有一个先进先出的队列来存储要执行的回调。
在这里插入图片描述

每当进入一个阶段,会执行最大数量为 n 个的回调,或者队列回调数少于 n,执行完后进入下一个阶段。

  • timers,执行setTimeout、setInterval 的回调。设定一个下限时间(如果写 0,会被改为 1),之后会执行这些回调,这里可能会被 poll 延迟
  • pending callbacks,执行 操作系统相关的回调,比如 TCP 连接还没连接上就收到了数据,一些操作系统会报错,这就会在这个队列加ECONNREFUSED事件
  • idle, prepare,node内部使用
  • poll,轮询,做两件事
    • 计算因为 I/O要阻塞和轮询多久(计算出来然后呢?)
    • 处理轮询队列里的事件
    • 如果到了poll 阶段
      • 如果轮询队列不为空,会同步执行最大数量为 n 的回调
      • 如果轮询队列为空,
        • 如果有setImmediate 会进入 check 阶段执行setImmediate的回调
        • 如果 timers到了时间(setTimeout、setInterval 那些),回到 timers 阶段
  • check,setImmediate回调在这里执行
  • close callbacks,一些关闭回调,比如 socket.on(‘close’, …)

了解完事件循环各个阶段,有什么用?可能能避免踩一些坑?虽然之前不了解这个机制,写 node 也没踩过坑🤦‍♂️,万一以后会遇到呢?

setTimeout(()=>{  console.log('timeout');
},0);
setImmediate(()=> {console.log('immediate');
});

这里似乎直觉上会先出 timeout,但实际 setTimeout 的时间最小是 1。如果机器性能一般,到 timers 阶段已经够 1ms 了,那就先输出 timeout;否则先输出 immediate

再来看这个

var fs = require('fs')fs.readFile(__filename, () => {setTimeout(() => {console.log('timeout');}, 0);setImmediate(() => {console.log('immediate');});
});

这里是先 immediate 再 timeout,因为是在回调里执行的,就是在 poll 阶段,当队列为空,immediate 优先级更高。

Promise 和process.nextTick 在一个事件循环后执行

再看看这题,看你晕不晕

async function async1(){console.log('async1 start')await async2()console.log('async1 end')}
async function async2(){console.log('async2')
}
console.log('script start')
setTimeout(function(){console.log('setTimeout0') 
},0)  
setTimeout(function(){console.log('setTimeout3') 
},3)  
setImmediate(() => console.log('setImmediate'));
process.nextTick(() => console.log('nextTick'));
async1();
new Promise(function(resolve){console.log('promise1')resolve();console.log('promise2')
}).then(function(){console.log('promise3')
})
console.log('script end')
script start
async1 start
async2
promise1
promise2
script end
nextTick
async1 end
promise3
setTimeout0
setImmediate
setTimeout3

为了方便对照,贴个图片左右对比
在这里插入图片描述

Promise 里的是立即执行的,resolve 和 reject 回调会加到微任务,所以 async1 start 后就会输出 async2。

也因此之后会走到 promise1,promise1 后,把 resolve 回调继续加到微任务,接着就输出 promise2。

之后就走到同步代码的最后 script end。

然后发现微任务队列不为空,最早的就是 nextTick,之后就是 await async2 后面的 async1 end 了。(这里可能疑问为啥都加了 await 了,没有同步执行,因为 async1()前面没加 await)

然后微任务队列还不为空,还有promise3。

之后进入事件循环,这里根据性能影响,最后三个可能会有区别,可能setTimeout3 还在 setImmediate 前面,也可能 setImmediate 在最前面。

好了搞清楚这些有啥用呢?可能是在之后遇到灵异事件时能较快找到原因吧? 顺便满足下好奇心,哈哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/450645.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

typecho 在文章中添加 bilibili 视频

一、获取视频来源: 可以有2种方式来定位一个 bilibili 视频: 第一种是使用 bvid 参数定位第二种是使用 aid 参数定位 如何获取这两个参数? 首先我们可以看看 bilibili 网站中的视频页面链接其实可以分为两种: 第一种是类似&a…

Kafka系列(一)【消息队列、Kafka的基本概念、Kafka的工作机制、Kafka可满足的需求、Kafka的特性、Kafka的应用场景】

kafka系列 一 一、消息队列1. 消息队列的来源2. 什么是消息队列3. 消息队列主要有哪些作用 二、Kafka的基本概念代理、生产者、消费者、消费者组主题、分区、副本、记录 三、了解 Kafka的工作机制-生产消息/消费消息四、Kafka可满足的需求五、Kafka的特性六、Kafka的场景 转自《…

[word] 怎么删除文字底纹 #职场发展#其他

怎么删除文字底纹 怎么删除文字底纹?我们在录入文字到文档的时候,或者是复制网上内容时,都会带有格式,有时候还会遇到删除不掉的问题。今天给大家分享小技巧,解决你的问题。 1、删除文字底纹 文档自带的底纹,删除技…

校园墙表白墙系统uniapp微信小程序

配置文件 (自动编号、配置参数名称、配置参数值); 前端开发:vue 语言:javapythonnodejsphp均支持 运行软件:idea/eclipse/vscode/pycharm/wamp均支持 框架支持:Ssm/django/flask/thinkphp/springboot/springcloud均支持 数据库 mysql 数据库工具&#x…

gin框架学习

文章目录 文章目录 gin框架学习一、使用net包搭建web服务器二、gin的初体验1.什么是gin?2.如何得到gin?(要保证你的go版本可以使用go mod)3.案例初体验 三、模板引擎四、gin框架学习1、gin处理json的数据2、query参数3、form表单提交4、gin获取uri参数5、gin参数绑定6、文件…

C#验证字符串是否包含汉字:用正则表达式 vs 用ASCII码 vs 用汉字的 Unicode 编码

目录 一、使用的方法 1.使用正则表达式验证字符串 2.使用正则表达式验证字符 3.用ASCII码判断 4.用汉字的 Unicode 编码范围判断 二、实例 1.源码 2.生成效果 验证一个字符串是否是纯汉字或者包含有汉字的前提,是VS编辑器的默认编码格式设置为:选…

shell命令以及运行原理 | 权限

Shell命令原理剖析 shell命令以及运行原理💦Linux权限的概念💦什么是权限❔Linux下有哪些权限身份❔Linux中文件属性解析 shell命令以及运行原理💦 Linux严格意义上说的是一个操作系统,我们称之为 “核心(kernel"…

Vulnhub-DC8

信息收集 # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:43:7c:b1, IPv4: 192.168.1.60 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.1.1 00:50:56:c0:00:08 VMware, Inc. 192.168.1.2 00:50:56:f…

《计算机网络简易速速上手小册》第8章:软件定义网络(SDN)与网络功能虚拟化(NFV)(2024 最新版)

第8章:软件定义网络(SDN)与网络功能虚拟化(NFV) 文章目录 8.1 SDN 架构与原理 - 智能网络的构建积木8.1.1 基础知识8.1.2 重点案例:使用 Python 控制 OpenFlow 交换机准备工作Python 脚本示例 8.1.3 拓展案…

SpringBoot注解--06--注解@Validated

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1 简述1.1 Validated作用1.2 所有参数注解含义1.3 异常处理1.4 Valid和Validated比较Valid级联校验 2.Validated 分组校验1.1为何要分组校验?1.2 代码案…

蓝桥杯每日一题----第k个数

题目:第k个数 主要为了学习数字的构造方法,如何快速求1~n中前缀为pre的数字的个数。 题目分析 一开始想的是把数字转化为字符串,然后丢给sort排序就行了,但是n太大了,会出现溢出问题。走到这里也从侧面反映了对所有…

金和OA jc6 UploadFileBlock 任意文件上传漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…