同步和异步程序的关联和区别是?Guide to Synchronous and Asynchronous Code

2024/3/12 发布
正在寻觅一份前端开发工作,如果您觉得这篇文章对你有所帮助,这是我的简历1

在这篇文章中你能学习和理解:NodeJS是如何工作、如何处理所有发送给服务器的函数(无论同步或者异步)和请求、Event Loops in NodeJS 。就是在NodeJS环境中同步代码和异步代码是如何执行的,以及event loop是如何管理异步代码的。

背景

想必每位前端开发工程师都能在NodeJS官网-学习入门 处看到这样一句话:NodeJS is an asynchronous event-driven JavaScript runtime environment designed to build scalable network applications.

理解什么是Asynchronous(异步)?

这里的Asynchronous指的是 那些在后台(background)处理不堵塞(blocking)任何其他请求(request)的JS函数(function)

理解什么是Event Loop (事件循环)

在NodeJS 环境中,Node用Event Loop 处理请求。

An event loop是一个内置在NodeJS环境中的事件监听者,它所拥有的一些函数随时准备去监听,处理和为事件进行输出。

用英文解释会更清楚:An event loop is an event-listener which functions inside the NodeJS environment and is always ready to listen, process, and output for an event.

PS:一个事件(an event)可以是鼠标事件,定时事件,键盘事件等。

理解什么是Synchronous programming(同步程序) and Asynchronous programming?

同步程序就是the code运行遵循书写下的序列(sequence),在同步程序中只有一个函数被调用并返回了一个值之后,下一行的函数才能执行。

让我们用以下的代码举个例子:

const listItems = function(items) {items.forEach(function(item) {console.log(item)})
}const items = ["Buy milk", "Buy coffee"]listItems(items)

The output will look like this:
“Buy milk”
“Buy coffee”

在这个例子中,当listItems(items)函数被调用后,它会循环抓取items数组元素,console.log(item)函数得到数组第一个元素后输出"Buy milk".然后console.log(item)再次执行时,通过数组第二个元素,输出"Buy coffee"

这就是所谓的函数遵循书写下的序列执行。

换句话来说,异步程序就是代码执行并不遵循明确的序列(sequence)。这些函数并不表现为一个程序中定义的序列,而仅仅当遇见确定的条件。

举个例子,setTimeOut() 表现为在提前指定的毫秒延迟过后执行一个任务。

setTimeOut(function(){return( console.log("Hello World!") )
}, 3000) 

这类函数并不是根据书写顺序一行行得运行,仅仅当他们需要被执行,和函数的声明无关,在这个例子中,在所有同步函数(synchronous function)都已经执行完过后,这个输出函数将会在3秒之后自动执行,在同步函数被执行完之前,异步函数会在后台被处理。

理解NodeJS 如何在后台处理异步函数 ,以及如何先执行所有同步函数?所有的这些机制,可以用NodeJS event loop轻松解释。

How Does an Event Loop Work?

用一个diagram来看看NodeJS event loop 如何执行一个简单的同步程序:
在这里插入图片描述
左上角是一个即将被执行的Node file,左下角是一个程序输出端,以及你会拥有 Call stack, Node APIs and Callback queue. 所有这些组成了这个 NodeJS environment.

对于同步程序,只需要关注call stack ,这是这个例子下,NodeJS 环境唯一会产生工作的地方。(call stack 就是一个数据结构,用于在程序中锁定所有函数的执行)

当程序开始执行,首先call stack 注入一个匿名main()函数,这个机制是NodeJS默认的。
在这里插入图片描述
接下来,变量a和b被创建,以及他们的和被存储在变量sum中。所有的取值都被存储在内存中。
现在,console.log()是一个函数,它被调用以及push到call stack ,然后执行,你就会在输出端的屏幕中看到它的输出结果。
在这里插入图片描述
当函数执行完毕,就会从call stack 中被移除。接着,当程序没有剩下的东西被调用,main()也会被移出call stack。以上就是同步程序执行的过程
在这里插入图片描述
在这里插入图片描述

现在,来看在NodeJS中异步程序如何执行。异步程序就需要call stack 、Node APIs、callback queue 全部一起参与处理。
看下面这个例子:
在这里插入图片描述
和上面的一样,当程序开始执行,第一步是main()被添加到call stack中。然后console.log("Start")被调用和添加到stack栈。进过处理,输出就在输出端被看见,接着就会从call stack 中被移除。
在这里插入图片描述
在这里插入图片描述
现在下一句是setTimeOut(...Zero...),函数被调用和添加到call stack。

因为这是一个异步函数,它不会在call stack中被处理,它从call stack 添加到Node APIs ,在Node APIs中:事件被注册,回调函数(callback function)被设置并在后台进行处理。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来setTimeOut(...Two..)同样的道理进入Node APIs,接着又一个callback function 被设置为在后台两秒之后处理。当这个时刻到来之前,其他函数都可以被执行。
这叫做非阻塞式行为:直到满足条件轮到他们执行之前,所有的同步函数首先在后台被处理和执行
在这里插入图片描述
接下来,console.log("End")函数被最后调用,并在call stack中处理,输出端可以看到输出结果。现在,所有的同步方法都被处理了,然后main()被移除call stack。

在后台,所有的异步函数被处理以及所有的回调函数被存储在callback queue,首先处理的一个将首先添加到队列中,以便在回调堆栈中执行。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Note: Asynchronous functions cannot run inside a callback stack until it gets emptied. That means that after main() is removed from call stack, only then can all asynchronous functions start executing.

现在他们被event loop一个个得推入call stack 并得到执行。
每次被调用时这些回调函数都会用console.log()函数打印value。
在这里插入图片描述
最后,这些都会被在执行过后被移除,现在call stack 再次清空了。
在这里插入图片描述
这就是NodeJS环境下 如何执行同步异步函数,以及event loop 如何管理调用异步函数。

Conclusion

在这篇文章中,你理解了NodeJS的内部工作机制,以及明白了异步程序如何被执行。

现在你应该理解为什么2秒的延迟函数没有阻塞其他的程序执行,你也明白为什么0秒的延迟函数在“End”输出后打印其值。

以上就是全部,我希望你们享受这篇文章的内容并学到一些新东西,分享这篇文章如果你觉得它有用!感谢你们的点赞关注和岗位内推!找到工作我会告诉大家!


  1. 我的简历:点击获取,欢迎随时联系我
    If you want to learn more about NodeJS and asynchronous programming, you can refer to this article ↩︎

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

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

相关文章

rk36566 uboot - dm 模型数据结构与常见接口

文章目录 一、数据结构1、udevice2、driver3、uclass4、uclass\_driver5、 总结6、device\_probe 二、常用接口1、udevice 创建接口1) device_bind_with_driver_data2) device_bind3) device_bind_by_name 2、uclass 操作函数1) uclass_get2) uclass_get_name3) uclass_find_de…

LeetCode 面试经典150题 27.移除元素

题目: 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数…

efcore coderfirst 生成数据库

使用 Entity Framework Core 的 Code First 方法开发时,你可以根据定义的实体模型和 DbContext 类自动生成数据库和表结构。下面的步骤将指导你如何使用 EF Core Code First 来生成数据库。 1. 安装必要的 NuGet 包 首先,确保已经安装了 Entity Framew…

Cesium 地图鼠标悬浮某个位置显示弹窗

问题:地图上显示了图标,在鼠标悬浮在地图上时,不出现弹窗,当悬浮在地图的图标上时,显示该图标的信息解决过程: 1.建立处理用户输入事件的画布,写出要在输入事件上执行的功能。 2.Cesium.ScreenS…

python调用jar中java方法 静态类为例

java package test;public class test {// run方法返回当前脚本路径public static String runV1(String s) {return "log: " System.getProperty(s);}}python import jpype from jpype import * import osif __name__ "__main__":print(os.environ[JAV…

java中的日期类

1.1 第一代日期类 第一代日期时间API主要有java.util.Date和日期时间格式化有关的java.text.DateFormat及其子类。 1.1.1 Date类 JDK1.0就在java.util包下面提供了Date类用于表示特定的瞬间,可以精确到毫秒。   通过API或源码,可以看出Date类的大部…

如何计算视频流需要的服务器带宽

一、如何计算视频流需要的服务器带宽 计算视频流需要的服务器带宽涉及多个因素,包括视频的编码质量、分辨率、帧率、同时观看的用户数量等。下面是一个基本的计算方法: 确定视频的平均比特率:视频的比特率(通常以比特/秒为单位)是衡量视频数据流量的关键指标。这取决于视…

vscode 导入前端项目

vscode 导入前端项目 导入安装依赖 运行 参考vscode 下载 导入 安装依赖 运行 在前端项目的终端中输入npm run serve

NCC环境配置

一、后端配置 安装eclipse汉化插件安装svn插件调试配置中配置启动参数 -Dnc.exclude.modules${FIELD_EX_MODULES} -Dnc.runModedevelop -Dnc.server.location${FIELD_NC_HOME} -DEJBConfigDir${FIELD_NC_HOME}/ejbXMLs -DExtServiceConfigDir${FIELD_NC_HOME}/ejbXMLs -…

C#,数值计算,数据测试用的对称正定矩阵(Symmetric Positive Definite Matrix)的随机生成算法与源代码

C.Hermite 1、对称矩阵 对称矩阵(Symmetric Matrices)是指以主对角线为对称轴,各元素对应相等的矩阵。在线性代数中,对称矩阵是一个方形矩阵,其转置矩阵和自身相等。1855年,埃米特(C.Hermite,1822-1901年)证明了别的数学家发现的一些矩阵类的特征根的特殊性质,如称为埃…

ASPICE-SYSSWE

文章主要内容: Automotive SPICE 过程参考模型 SYS.1 需求挖掘 过程ID SYS.1 过程名称 需求挖掘 过程目的 需求挖掘过程的目的是:在产品和/或服务的整个生命周期内收集、处理和跟踪不断变化的利益相关方的需要和需求,从而建立一个需求基线&#x…

交换机/路由器的存储介质-思科

交换机/路由器的存储介质-思科 本文主要介绍网络设备的存储介质组成。 RAM(random-accessmemory,随机访问存储器) RAM中内容断电丢失,主要用于运行操作系统、运行配置文件、IP 路由表:、ARP 缓存、数据包缓存区。 ROM(read-only memory,只…

uniapp遇到的问题

【uniapp】小程序中input输入框的placeholder-class不生效解决办法 解决:写在scope外面 uniapp设置底部导航 引用:https://www.jianshu.com/p/738dd51a0162 【微信小程序】moveable-view / moveable-area的使用 https://blog.csdn.net/qq_36901092/…

持续创新引领计算机行业在数字经济时代的航向

受2024年政府工作报告的启发,计算机行业正站在新的发展十字路口。政府报告不仅为计算机行业的未来描绘了清晰的轮廓,更为行业的实践提供了扎实的政策支撑和发展空间。本文将深入分析计算机行业在数字化经济大潮中的新机遇与挑战,并对企业和从…

服务器数据恢复—raid5热备盘上线同步数据失败的如何恢复数据

服务器数据恢复环境&故障&分析: 一台存储上有一组由多块硬盘组建的raid5阵列,该raid5阵列中的一块硬盘掉线,热备盘自动上线同步数据的过程中,raid阵列中又有一块硬盘掉线,热备盘的数据同步被中断,r…

Apache Paimon 的 Query Service 使用

Query Service 可以运行Flink流作业来启动表的查询服务,当QueryService存在时,Flink Lookup Join将优先从中获取数据,这将有效地提高查询性能。 Flink SQL CALL sys.query_service(database_name.table_name, parallelism);Flink Action …

24计算机考研调剂 | 浙江工商大学【官方】

2024年浙江工商大学信电学院调剂咨询通道已开启! 考研调剂招生信息 根据今年初试情况,预计我院信息与通信工程(081000)一级学科硕士点、电子信息(人工智能领域)(085410)专业学位硕士…

【刷题训练】LeetCode:557. 反转字符串中的单词 III

557. 反转字符串中的单词 III 题目要求 示例 1: 输入:s “Let’s take LeetCode contest” 输出:“s’teL ekat edoCteeL tsetnoc” 示例 2: 输入: s “Mr Ding” 输出:“rM gniD” 思路: 第一步&am…

Python朗读在线音频和本地音频的三种方法

在日常的Python软件开发中,我们经常会遇到一个非常重要的功能需求——让程序能够读取并显示文本内容。那么,如何实现这一功能呢?本文将提供几种方法供大家参考,其中第二种方法是最推荐的。 一、pyttsx3法 采用这个第三方模块&am…

Android studio 性能调试

一、概述 Android studio 的Profiler可用来分析cpu和memory问题,下来进行说明介绍。 二、Android studio CPU调试 从开发模拟器或设备中启动应用程序; 在 Android Studio 中,通过选择View > Tool Windows > Profiler启动分析器。 应…