Node.js 入门教程 28 Node.js 事件循环

news2024/11/24 18:57:37

Node.js 入门教程

Node.js官方入门教程

Node.js中文网

本文仅用于学习记录,不存在任何商业用途,如侵删

文章目录

      • Node.js 入门教程
      • 28 Node.js 事件循环
        • 28.1 介绍
        • 28.2 阻塞事件循环
        • 28.3 调用堆栈
        • 28.4 一个简单的事件循环的阐释
        • 28.5 入队函数执行
        • 28.6 消息队列
        • 28.7 ES6 作业队列

28 Node.js 事件循环

28.1 介绍

事件循环是了解 Node.js 最重要的方面之一。

为什么这么重要? 因为它阐明了 Node.js 如何做到异步且具有非阻塞的 I/O,所以它基本上阐明了 Node.js 的“杀手级应用”,正是这一点使它成功了。

Node.js JavaScript 代码运行在单个线程上。 每次只处理一件事。

这个限制实际上非常有用,因为它大大简化了编程方式,而不必担心并发问题。

只需要注意如何编写代码,并避免任何可能阻塞线程的事情,例如同步的网络调用或无限的循环。

通常,在大多数浏览器中,每个浏览器选项卡都有一个事件循环,以使每个进程都隔离开,并避免使用无限的循环或繁重的处理来阻止整个浏览器的网页。

该环境管理多个并发的事件循环,例如处理 API 调用。 Web 工作进程也运行在自己的事件循环中。

主要需要关心代码会在单个事件循环上运行,并且在编写代码时牢记这一点,以避免阻塞它。

28.2 阻塞事件循环

任何花费太长时间才能将控制权返回给事件循环的 JavaScript 代码,都会阻塞页面中任何 JavaScript 代码的执行,甚至阻塞 UI 线程,并且用户无法单击浏览、滚动页面等。

JavaScript 中几乎所有的 I/O 基元都是非阻塞的。 网络请求、文件系统操作等。

被阻塞是个异常,这就是 JavaScript 如此之多基于回调(最近越来越多基于 promise 和 async/await)的原因。

28.3 调用堆栈

调用堆栈是一个 LIFO 队列(后进先出)。

事件循环不断地检查调用堆栈,以查看是否需要运行任何函数。

当执行时,它会将找到的所有函数调用添加到调用堆栈中,并按顺序执行每个函数。

你知道在调试器或浏览器控制台中可能熟悉的错误堆栈跟踪吗? 浏览器在调用堆栈中查找函数名称,以告知你是哪个函数发起了当前的调用:

在这里插入图片描述

28.4 一个简单的事件循环的阐释

举个例子:

const bar = () => console.log('bar')
const baz = () => console.log('baz')

const foo = () => {
    console.log('foo')
    bar()
    baz()
}

foo()

在这里插入图片描述

foo
bar
baz

当运行此代码时,会首先调用 foo()。 在 foo() 内部,会首先调用 bar(),然后调用 baz()

此时,调用堆栈如下所示:

在这里插入图片描述

每次迭代中的事件循环都会查看调用堆栈中是否有东西并执行它直到调用堆栈为空:

在这里插入图片描述

28.5 入队函数执行

上面的示例看起来很正常,没有什么特别的:JavaScript 查找要执行的东西,并按顺序运行它们。

让我们看看如何将函数推迟直到堆栈被清空。

setTimeout(() => {}, 0) 的用例是调用一个函数,但是是在代码中的每个其他函数已被执行之后。

举个例子:

const bar = () => console.log('bar')

const baz = () => console.log('baz')

const foo = () => {
    console.log('foo')
    setTimeout(bar, 0)
    baz()
}

foo()

该代码会打印:

在这里插入图片描述

当运行此代码时,会首先调用 foo()。 在 foo() 内部,会首先调用 setTimeout,将 bar 作为参数传入,并传入 0 作为定时器指示它尽快运行。 然后调用 baz()。

此时,调用堆栈如下所示:

在这里插入图片描述

这是程序中所有函数的执行顺序:

在这里插入图片描述

【为什么会这样呢?】

28.6 消息队列

当调用 setTimeout() 时,浏览器或 Node.js 会启动定时器。 当定时器到期时(在此示例中会立即到期,因为将超时值设为 0),则回调函数会被放入“消息队列”中。

在消息队列中,用户触发的事件(如单击或键盘事件、或获取响应)也会在此排队,然后代码才有机会对其作出反应。 类似 onLoad 这样的 DOM 事件也如此。

事件循环会赋予调用堆栈优先级,它首先处理在调用堆栈中找到的所有东西,一旦其中没有任何东西,便开始处理消息队列中的东西。

我们不必等待诸如 setTimeout、fetch、或其他的函数来完成它们自身的工作,因为它们是由浏览器提供的,并且位于它们自身的线程中。 例如,如果将 setTimeout 的超时设置为 2 秒,但不必等待 2 秒,等待发生在其他地方。

28.7 ES6 作业队列

ECMAScript 2015 引入了作业队列的概念,Promise 使用了该队列(也在 ES6/ES2015 中引入)。 这种方式会尽快地执行异步函数的结果,而不是放在调用堆栈的末尾。

在当前函数结束之前 resolve 的 Promise 会在当前函数之后被立即执行。

有个游乐园中过山车的比喻很好:消息队列将你排在队列的后面(在所有其他人的后面),你不得不等待你的回合,而工作队列则是快速通道票,这样你就可以在完成上一次乘车后立即乘坐另一趟车。

示例:

const bar = () => console.log('bar')


const baz = () => console.log('baz')


const foo = () => {
  console.log('foo')
  setTimeout(bar, 0)
  new Promise((resolve, reject) =>
    resolve('应该在 baz 之后、bar 之前')
  ).then(resolve => console.log(resolve))
  baz()
}


foo()

这会打印:

在这里插入图片描述

这是 Promise(以及基于 promise 构建的 async/await)与通过 setTimeout() 或其他平台 API 的普通的旧异步函数之间的巨大区别。

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

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

相关文章

ICC2:Design Planning(03)Power Network Synthesis

在shape block之后,接下来可以做pg规划。power network creation可以分为如下几个部分: 1.Add Power Pad 在规划power mesh之前需要先插power pad,所以要在create abstract阶段load upf,如果规划power mesh时没有power pad,也需要…

Java+JSP基于ssm高校网上教材征订系统-计算机毕业设计

项目介绍 随着高校规模的扩大和教学改革的不断深入,高校的教学和科研水平都在稳步提高,但高校的教材选订环节却仍存在着许多问题。目前,高校的教材选订工作大多采用的是手工方式,不仅费时、费力,而且还存在许多人为的…

Seal库官方示例(二):encoders.cpp解析

补充一个常用的SIMD操作原理 图片来自的Hang Shao的文章。 完整代码 这个代码主要功能是编码明文,使得能够使用更加完整的明文多项式(前一个只用到了一个多项式的常量),也就是SIMD操作。主要包含了两个部分,一个是BG…

Animator动画状态机

1、有限状态机 有限状态机(Finite - state machine, FSM),又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型 有限:表示是有限度的不是无限的 状态&#x…

机器人开发--减速机

机器人开发--减速机1 概述介绍功能分类按照传动类型可分为:按照传动级数不同可分为:按照齿轮形状可分为:按照传动的布置形式可分为:应用2 电机使用减速机原因3 RV减速机、谐波减速机 和 行星减速机RV减速机谐波减速机行星减速机蜗轮蜗杆减速机4 机器人各…

社区系统项目复盘-1

文章目录技术架构开发环境开发社区首页技术架构 Spring BootSpring、Spring MVC、MyBatisRedis、Kafka、ElasticsearchSpring Security、Spring Actuator 开发环境 构建工具:Apache Maven 版本:3.6.1集成开发环境:IntelliJ IDEA数据库&…

R3LIVE代码详解(四)

0. 简介 上一节中,我们过完了VIO中的状态预测以及特征点跟踪部分。此时我们已经拿到了光流的特征点信息,而这部分越来越接近我们想要去讲的帧到帧的VIO部分了。这一节,我们将围绕着VIO部分来进行讲解 1. PNP误差更新 我们从之前的博客《经…

人工智能前沿——未来AI技术的五大应用领域

关注“PandaCVer”公众号 >>>深度学习Tricks&#xff0c;第一时间送达<<< 目录 一、航空航天 二、医疗保健 三、建筑行业 四、能源领域 五、供应链 关于YOLO算法改进及论文投稿可关注并留言博主的CSDN/QQ >>>一起交流&#xff01;互相学习&…

力扣(LeetCode)1758. 生成交替二进制字符串的最少操作数(C++)

模拟 我们最终串只有两种形态 ① 1010101…1010101\dots1010101… 偶数位全 111 &#xff0c;奇数位全 000 &#xff0c; ② 0101010…0101010\dots0101010… 偶数位全 000 &#xff0c;奇数位全 111 &#xff0c; 我们统计将偶数位全变成 111 &#xff0c;奇数位全变成 000 的…

传奇外网架设全套图文教程-Hero引擎

当你拿到一个Hero引擎的版本&#xff0c;首先查看一下版本内文件是否完整&#xff0c;一个完整的Hero版本应该包括&#xff1a;DBServer、LoginGate、LoginSrv、LogServer、Mir200、Mud2、RunGate、SelGate、网站和GameCenter.exe&#xff08;引擎&#xff09;&#xff0c;以上…

龙芯 处理器

龙芯&#xff1a;国内最早自主研发芯片厂商&#xff0c;MIPS 架构体系自主化程度高 龙芯是中国科学院计算所自主研发的通用CPU&#xff0c;采用自主LoongISA指令系统&#xff0c;兼容MIPS指令 n “龙芯”是我国最早研制的高性能通用处理器系列&#xff0c;于 2001 年在中科院计…

【每日一题Day42】生成交替二进制字符串的最小操作数 | 模拟 位运算

生成交替二进制字符串的最小操作数【LC1758】 You are given a string s consisting only of the characters 0 and 1. In one operation, you can change any 0 to 1 or vice versa. The string is called alternating if no two adjacent characters are equal. For example,…

黑马点评--用户签到

用户签到 BitMap用法签到功能签到统计 BitMap用法&#xff1a; 我们按月来统计用户签到信息&#xff0c;签到记录为1&#xff0c;未签到则记录为0.&#xff08;布隆过滤器就是采用这种结构&#xff09; 把每一个bit位对应当月的每一天&#xff0c;形成了映射关系。用0和1标示…

docker的安装

1、docker官网 Install Docker Engine on CentOS | Docker Documentation yum -y install gcc yum -y install gcc-c yum install -y yum-utils yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum makecache fast yum insta…

原型(克隆)模式

文章目录思考原型(克隆)模式1.原型模式的本质2.何时选用原型模式3.优缺点4.实现原型模式(浅克隆)原型模式(深克隆)java浅克隆java深克隆思考原型(克隆)模式 原型模式顾名思义通过一个接口实现快速创建对象 1.原型模式的本质 原型模式的本质:克隆生成对象。 克隆是手段&#xff…

【Ubuntu】进程与线程编程实验

文章目录进程与线程实验一&#xff1a;创建进程基础版&#xff1a;创建父子线程 fork基础版&#xff1a;父子线程交替运行基础版&#xff1a;创建进程 文件写入练习版&#xff1a;创建线程 子读父阻塞实验二&#xff1a;线程共享进程中的数据实验三&#xff1a;多线程实现单词统…

总结709(bug集合)

今天不知道怎么了&#xff0c;那个曾弄了我20多天的冒险模块&#xff0c;在今天&#xff0c;差不多要完工了。弄出的那一刻&#xff0c;有的是喜悦&#xff0c;但之后&#xff0c;更多的是叹气。 也就是从此刻我才意识到&#xff0c;我曾自认为很崇高的职位&#xff0c;可能事…

传奇出现黑屏卡屏不动是怎么回事

在写这篇文章之前&#xff0c;先给给大家说一下&#xff0c;这篇文章写的是出现黑屏、卡屏不动是我们玩传奇的时候出现的&#xff0c;而不是在架设传奇时候出现的&#xff0c;所以要特别是注意一下&#xff0c;架设和玩出现黑屏是完全不一样的&#xff0c;所以解决方案也不一样…

驱动开发 platfrom总线驱动的三种方式

驱动的分隔与分离&#xff1a; 对于 Linux 这样一个成熟、庞大、复杂的操作系统&#xff0c;代码的重用性非常重要&#xff0c;在驱动程序&#xff0c;因为驱动程序占用了 Linux 内核代码量的大头&#xff0c;如果不对驱动程序加以管理&#xff0c;任由重复的代码肆意增加&…

基于深度学习的合成孔径雷达自聚焦

文章目录引言什么是合成孔径雷达什么是自聚焦经典自聚焦方法基于机器学习的方法基于极速学习机的方法基于深度学习的SAR自聚焦代码附录引言 本文全面介绍合成孔径雷达自聚焦概念和方法。想获取更为详尽的描述&#xff0c;请参考以下几篇论文, 如果数据或代码对你的研究有用&am…