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.mzph.cn/news/666603.shtml

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

相关文章

Acwing---827.双链表

双链表 1.题目2.基本思想3.代码实现 1.题目 实现一个双链表,链表初始为空,支持5种操作: 在最左侧插入一个数;在最右侧插入一个数;将第 k k k 个插入的数删除;在第 k k k个插入的数左侧插入一个数&#…

安装Canal

安装和配置Canal 下面我们就开启mysql的主从同步机制,让Canal来模拟salve 1.开启MySQL主从 Canal是基于MySQL的主从同步功能,因此必须先开启MySQL的主从功能才可以。 这里以之前用Docker运行的mysql为例: 1.1.开启binlog 打开mysql容器…

景联文科技受邀出席全国信标委生物特征识别分委会二届五次全会

全国信息技术标准化技术委员会生物特征识别分技术委员会(SAC/TC28/SC37,以下简称“分委会”)二届五次全会于2024年1月30日在北京顺利召开,会议由分委员秘书长王文峰主持。 分委会由国家标准化管理委员会批准成立,主要负…

社交平台内容创作未来会有哪些方向?

内容为王的时代下,企业如果想要通过社交平台占据用户心智,可以找到适合自己的内容营销策略,好的内容能够与消费者建立信任关系,今天 媒介盒子就来和大家聊聊:社交平台内容创作的方向。 一、 内容逐渐细分 相比于原来…

WorkPlus打造个性化移动门户,实现协作创新与工作高效

在移动办公逐渐成为企业工作方式的主流趋势下,构建高效的移动门户平台对于提升信息传递与团队协作效能至关重要。移动门户作为企业信息交流和协作的重要枢纽,WorkPlus以其领先的功能和卓越的性能,助力企业实现智能移动门户平台的搭建。 为何…

在WORD中设置公式居中编号右对齐设置方式

1 软件环境 Office Microsoft Office LTSC 专业增强版2021 2 最终效果 3 操作步骤 编辑公式;光标定位到公式的最后(不是行的最后);输入#编号光标定位在公式最后(不是行的最后),按Enter键回车…

R3 下动态加载的模块的保护(一)

前言 在 R3 下防护动态加载的模块不被意外卸载需要很多的策略,比如:LDR 断链、VAD 记录擦除、PE 头擦除、修改入口函数、内存注入等。文本我们将浅析模块静态化技术这一项技术。模块静态化是一个很常见的模块保护技术,它通过修改模块的引用计…

建筑工程答案在哪搜?九个免费好用的大学生搜题工具 #经验分享#知识分享

大学生必备,这条笔记大数据一定定要推给刚上大学的学弟学妹!! 1.七燕搜题 这是一个公众号 解题步骤详细解析,帮助你理解问题本质。其他考试领域也能找到答案。 下方附上一些测试的试题及答案 1、据《素问太阴阳明论》所论&…

爬取58二手房并用SVR模型拟合

目录 一、前言 二、爬虫与数据处理 三、模型 一、前言 爬取数据仅用于练习和学习。本文运用二手房规格sepc(如3室2厅1卫)和二手房面积area预测二手房价格price,只是练习和学习,不代表如何实际意义。 二、爬虫与数据处理 import requests import cha…

关于Clone

关于Clone 一般情况下,如果使用clone()方法,则需满足以下条件。 1、对任何对象o,都有o.clone() ! o。换言之,克隆对象与原型对象不是同一个对象。 2、对任何对象o,都有o.clone().getClass() o.getClass()。换言之&a…

背景样式de七七八八

一,简介 背景属性可以设置背景颜色、背景图片、背景平铺、背景图片位置、背景图像固定等。 1.1背景颜色(background-color) background-color:transparent/color; 默认值为transparent(透明的&#xff…

Rust 第一个rust程序Hello Rust️

文章目录 前言一、vscode 安装rust相关插件二、Cargo New三、vscode调试rustLLDB 前言 Rust学习系列。今天就让我们掌握第一个rust程序。Hello Rust 🦀️。 在上一篇文章我们在macOS成功安装了rust。 一、vscode 安装rust相关插件 以下是一些常用的 Rust 开发插件…

从传统到现代:易点易动固定资产管理系统利用RFID技术高效管理固定资产

近年来,随着RFID技术的发展与成熟,它被越来越多地应用于企业资产管理领域。易点易动推出的固定资产管理系统就将RFID技术深度整合,实现了企业固定资产管理模式的跨越式变革。 传统管理模式的不足 传统的手工登记式管理模式在企业固定资产管理中存在很多问题: 信息录入缺乏规范…

幻兽帕鲁服务器自动重启备份-python

幻兽帕鲁服务器自动重启备份-python 1. 前置知识点2. 目录结构3. 代码内容4. 原理解释5. 额外备注 基于python编写的服务器全自动管理工具,能够实现自动定时备份存档,以及在检测到服务器崩溃之后自动重新启动,并且整合了对于frp端口转发工具的…

c语言:贪吃蛇的实现

目录 贪吃蛇实现的技术前提: Win32 API介绍 控制台程序(console) 控制台屏幕上的坐标 GetStdHandle GetConsoleCursorInfo CONSOLE_CURSOR_INFO SetConsoleCursorInfo SetConsoleCursorPosition GetAsyncKeyState 宽字符的打印 …

进程中线程使用率偏高问题排查

1. top命令查看CPU使用率高的进程 2. top -H -p 15931(进程PID) 查看进程下的线程 3. printf "%x\n" 17503(线程PID) 线程PID 10进制转16进制 0x445f 4. jstack -l 15931(JVM进程PID) 导出java进程栈信息,里面包含线程nid0x445f和所在的类&#xff0…

【AG32VF407】国产MCU+FPGA Verilog双边沿检测输出方波

视频讲解 [AG32VF407]国产MCUFPGA Verilog双边沿检测输出方波 实验过程 本次使用使用AG32VF407开发板中的FPGA,使用双clk的双边沿进行检测,同步输出方波 同时可以根据输出的方波检测clk的频率,以及双clk的相位关系,如下为verilog…

生活资料 伊舍小镇

生活资料 伊舍小镇 电费交付—国家电网 咨询:95598 用户:*** 查询:微信“国网北京电力”公众号→我的用电→余额查询→立即购电 支付:微信→我→服务→生活缴费→自动缴费 燃气费交付-北京燃气 咨询:96777 用户&am…

考研/计算机二级数据结构刷题之顺序表

目录 第一题 顺序表的初始化,销毁,头插,尾插,头删,尾删,指定位置插入,指定删除以及打印 第二题 移除元素 题目链接: OJ链接 题目详解:移除元素 第三题:删…

ONLYOFFICE 8.0 测评:重塑办公新标杆,你绝对不能错过的版本!

ONLYOFFICE 8.0 测评:办公新境界的全新突破 一、全新的界面设计二、可填写的 PDF 表单 免费表单模板三、双向文本四、电子表格中的新增功能五、协作功能升级六、跨平台性能优化七、强化安全性八、更丰富的插件生态九、辅助功能:优化的屏幕朗读器 随着科…