为什么 Node.js 是异步的?

2024-04-10

实际上没有人问过这个问题(从我得到的所有“建议”以及我在这里问之前的搜索)。

那么为什么 Node.js 是异步的呢?

经过一番研究后我得出的结论是:

像 PHP 和 Python 这样的语言是脚本语言(我可能对脚本语言的实际语言是错误的),而 JavaScript 不是。 (我想这是因为 JS 无法编译?)

Node.js 在单线程上运行,而脚本语言则使用多线程。

异步意味着无状态,并且连接是持久的,而同步则(几乎)相反。

也许答案可以在上面提到的某个地方找到,但我仍然不确定。

我与该主题相关的第二个问题也是最后一个问题是:

JavaScript 可以成为同步语言吗?

附言。我知道你们中有些人会问“为什么要让 JS 同步?”在你的回答中,但事实是我不知道。我只是问这些类型的问题,因为我确信除了我自己之外还有更多的人思考过此类问题。


Node.js 在单线程上运行,而脚本语言则使用多线程。

技术上不行。 Node.js 使用多个线程,但只有一个执行线程。后台线程用于处理 IO,以使所有异步功能发挥作用。有效地处理线程是一件非常痛苦的事情,因此下一个最佳选择是在事件循环中运行,以便在后台线程在 IO 上被阻塞时代码可以运行。

异步意味着无状态,并且连接是持久的,而同步则(几乎)相反。

不必要。您可以非常轻松地在异步系统中保留状态。例如,在 JavaScript 中,您可以使用bind()绑定一个this到一个函数,从而在函数返回时显式地保留状态:

function State() {
    // make sure that whenever doStuff is called it maintains its state
    this.doStuff = this.doStuff.bind(this);
}
State.prototype.doStuff = function () {
};

异步意味着不等待操作完成,而是注册侦听器。这种情况在其他语言中经常发生,尤其是任何需要接受用户输入的语言。例如,在 Java GUI 中,您不会阻止等待用户按下按钮,而是向 GUI 注册一个侦听器。

我与该主题相关的第二个问题也是最后一个问题是:

JavaScript 可以成为同步语言吗?

从技术上讲,所有语言都是同步的,甚至 Javascript 也是如此。然而,Javascript 在异步设计中工作得更好,因为它被设计为单线程。

基本上有两种类型的程序:

  • CPU 限制 - 让它运行得更快的唯一方法是获得更多的 CPU 时间
  • IO 限制 - 花费大量时间等待数据,因此更快的处理器并不重要

视频游戏、数字计算器和编译器受 CPU 限制,而 Web 服务器和 GUI 通常受 IO 限制。 Javascript 相对较慢(因为它非常复杂),因此它无法在 CPU 密集型场景中竞争(相信我,我已经编写了相当多的 CPU 密集型 Javascript)。

Javascript 不是根据类和对象进行编码,而是根据可以串在一起的简单函数进行编码。这在异步设计中非常有效,因为可以编写算法来增量处理数据。IO(尤其是网络 IO)非常慢,因此数据包之间有相当多的时间。

Example

假设您有 1000 个实时连接,每个连接每毫秒传送一个数据包,处理每个数据包需要 1 微秒(非常合理)。我们还假设每个连接发送 5 个数据包。

在单线程同步应用程序中,每个连接都将被串行处理。所花费的总时间为 (5*1 + 5*.001) * 1000 毫秒,即 ~5005 毫秒。

在单线程异步应用程序中,每个连接都将并行处理。由于每个数据包需要 1 毫秒,而处理每个数据包需要 0.001 毫秒,因此我们可以处理数据包之间的每个连接的数据包,因此我们的公式变为:1000*.001 + 5*1 毫秒,即~6 毫秒。

解决这个问题的传统方法是创建更多线程。这解决了 IO 问题,但是当连接数增加时,内存使用量(线程消耗大量内存)和 CPU 使用量(将 100 个线程复用到 1 个核心比 1 个线程复用到 1 个核心更难)也随之增加。

然而,也有缺点。如果您的 Web 应用程序碰巧还需要进行一些繁重的数字运算,那么您就是 SOL,因为在您处理数字时,连接需要等待。线程解决了这个问题,因为当数据准备好等待 IO 的线程时,操作系统可以换出 CPU 密集型任务。此外,node.js 绑定到单核,因此除非启动多个实例和代理请求,否则您无法利用多核处理器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Node.js 是异步的? 的相关文章

  • 在javascript中访问函数内的实例变量?

    如何以最简单的方式访问函数内的实例变量 function MyObject Instance variables this handler Methods this enableHandler function var button doc
  • 此页面上的脚本导致 ie 运行缓慢

    问题就在标题中 IE 行为异常 并说有一个脚本运行缓慢 FF 和 Chrome 没有这个问题 我怎样才能找到问题所在 那个页面有很多JS 手动检查不是一个好主意 EDIT 这是我正在处理的一个项目的页面 但我需要一个工具来查找问题 End
  • 访问 nuxt 配置文件中的存储

    我想添加通过 Nuxt 静态生成的动态路由 我定义了一个客户端 服务器端存储asyncData方法 我想将这个存储值 一个数组 映射到我的nuxt config js文件使其成为 动态 静态 路线图nuxt generate命令 但如何访问
  • Nodejs 调试生产中的错误

    我有一个在生产环境中运行的 Nodejs 脚本 我不太可能 千分之一 遇到这样的错误 TypeError value is out of bounds at checkInt buffer js 1009 11 at Buffer writ
  • JavaScript 将键添加到数组中的每个值

    我下面有这个数组 它由一个简单的数组组成 我想要完成的是放一把钥匙id在每个数组值前面以实现类似的效果 id a id b id c id d 有没有一种简单的方法可以做到这一点 任何帮助将不胜感激 谢谢 var test a b c d
  • 如何在 React Native 上显示 SVG 文件?

    我想显示 svg 文件 我有一堆 svg 图像 但我找不到显示的方式 我尝试使用Image and Use的组成部分反应本机 svg https github com magicismight react native svg但他们不这样做
  • 将 Firebase FCM 添加到 ReactJS 应用程序

    我正在尝试向我的 ReactJS 应用程序中的用户发送推送通知 我已添加 firebase 请求用户通知权限 这正在发挥作用 但现在我想注册设备令牌 但这给了我错误 消息传递 我们无法注册默认的 Service Worker 无法注册 Se
  • 如果一个对象结构与另一个对象结构不匹配/不匹配,如何引发异常

    我将读取格式正确的用户输入对象 也就是说 输入对象现在可以具有接口中未定义的任何键或子结构 如果用户提供了无效的对象 我如何抛出异常 预定义接口 export interface InputStructureInterface tableN
  • 如何将 arraylist 从 servlet 传递到 javascript?

    我通过在属性中设置数组列表并将其转发到 jsp 来从 servlet 传递数组列表 Servlet ArrayList
  • 当我多次调用 requestAnimationFrame 时会发生什么

    我的意思是一次调用多个具有相同功能的 requestAnimationFrame function Draw DoSomething function AFunc prepare something requestAnimationFram
  • ES6继承:使用`super`访问父类的属性

    JavaScript 的super关键字 当我在 Chrome Babel TypeScript 上运行代码时 得到了不同的结果 我的问题是哪个结果是正确的 规范的哪一部分定义了这种行为 下面的代码 class Point getX con
  • 监听文件夹和文件(更改)

    可以直接在 PHP 或 Node 上监听文件夹和文件的更改 通过事件 还是我需要创建自己的方法来执行此操作 Example 我需要听文件夹 user 如果我将一些文件添加到该目录中 PHP 或 Node 会收到信息并运行PathEvent
  • 如何使用新的analytics.js跟踪多个帐户?

    我需要使用 Google 的新的analytics js 跟踪一个页面上两个帐户的综合浏览量 有大量教程和示例如何使用较旧的 ga js 进行操作 但我发现的只是这个分析文档页面 https developers google com an
  • 如何获取nodejs程序中的nodejs版本?

    In a Node js 的调试器 https github com rocky trepanjs 有一个命令显示V8版本和调试器包版本 如何获取nodejs版本 我想我基本上可以运行命令node version or nodejs ver
  • javascript 是否有等效的 __repr__ ?

    我最接近Python的东西repr这是 function User name password this name name this password password User prototype toString function r
  • 如何动态调整jqgrid到当前窗口大小?

    如何动态调整jqgrid到当前窗口大小 基于javascript jQuery 最好的例子在这里 TinyMCE 去 http www tinymce com tryit full php http www tinymce com tryi
  • ChartJs:如何按时间值(而不是像素)以编程方式平移

    我使用的是chartJs 3 6 1 和 Chartjs plugin zoom 1 2 1 但我认为这并不重要 我有 2 个时间序列折线图 当我通过拖放平移一个图表时 我也想移动 平移另一个图表 为此 我为 graphA 启用了缩放 平移
  • 使用 ref 触发反应 dropzone 不起作用

    我正在实现这个库 https github com felixrieseberg React Dropzone Component https github com felixrieseberg React Dropzone Compone
  • ThreeJS 中阴影的奇怪行为

    所以我有一个 ThreeJS 场景 并且添加了一些球体 多材质 我还添加了定向光 this light new THREE DirectionalLight 0xFFFFFF 1 this light position set 2 10 2
  • ng-include 和 ng-view 不同时加载

    下面是我的应用程序的结构 很简单 页眉和页脚是非常小的文件 而主页上的 ng view 要大得多 当我进入该页面时 我注意到了这一点 首先加载两个 ng include 然后 ng view 出现 页脚被推到底部 页脚闪烁大约 0 1 秒

随机推荐

  • 自引用 has_many 的问题:通过 Rails 中的关联

    我今天正在阅读有关自引用 has many through 数据情况的内容 因为我正在尝试构建一个使用它们的 Rails 应用程序 我找到了这个示例情况 http blog hasmanythrough com 2007 10 30 sel
  • 如何查看当前显示的html页面的来源(动态)而不是原始页面? [复制]

    这个问题在这里已经有答案了 大家好 作为一名狂热的 Firefox 用户 我使用诸如 Style 和 Greasemonkey 之类的插件来修改页面的默认样式 然而 浏览器的视图 gt 页面源选项仅显示原始形式的页面 而不显示由脚本或样式操
  • 如何从控制器访问 REST API 的所有可用路由?

    我正在使用 Spring Boot 创建一个 REST API 我想当用户发出请求时返回所有可用路由的列表 作为 JSON 例如 help或者甚至只是到服务器的根端点 即在我的情况下 因为我在本地工作 localhost 8080 我知道我
  • 天数累计

    我有一个 MySQL 表 如下所示 date count 2010 01 01 5 2010 01 02 6 2010 01 03 7 如何将每一天的总和累加到下一天 所以结果是这样的 date acum per day 2010 01 0
  • UML 聚合可以是双向的吗?

    我正在 Python 中实现一个具有 MVC 模式的应用程序 具有以下类定义 class Controller object def init self model view self model model self view view
  • Python:如何将数据帧字典转换为一个大数据帧,其中列名是前一个字典的键?

    所以我的数据框是由许多单独的 Excel 文件组成的 每个文件都以日期作为文件名 并在电子表格中显示当天水果的价格 因此电子表格看起来像这样 15012016 Fruit Price Orange 1 Apple 2 Pear 3 1601
  • 为什么在音频标签内使用源标签会阻止 loaddata 事件触发?

    为了更好的可访问性 我们需要第二组替代的播放 暂停控件和 在用户 Kento Nishi 的帮助下 我们成功搬离DEMO A https jsfiddle net j5oxhq38 只有 1 个音频播放控件 DEMO B https jsf
  • 在 selenium 中将页面向上滚动到顶部

    如何将网页滚动到页面顶部 我知道将页面滚动到底部是 window scrollTo 0 document body scrollHeight 就像这样可以将页面滚动到顶部吗 要滚动到页面顶部 只需滚动到0 0 window scrollTo
  • Jest + React-testing-library - 等待模拟的异步函数完成

    My componentDidMount 触发对异步函数的调用 但根据该函数的结果 它可能不会导致任何 DOM 更改 有什么方法可以等待该函数在测试中完成吗 这是一个示例 单击按钮最初被禁用 如果异步函数返回 true 则应启用单击按钮 m
  • Magento 多个 Authorize.net 网关

    我有一个用于处理信用卡付款的 CAD 和 USD 网关帐户 这两个帐户均来自支持 Authorize net API 的支付提供商 我已经使用 Magento 的内置 Authorize net 支持成功配置了一个 但是如何配置第二个 Au
  • 在终结器中抛出异常以强制执行 Dispose 调用:

    这是我认为推荐的典型 IDisposable 实现 SomeClass Dispose false public void Dispose GC SuppressFinalize this Dispose true protected vi
  • 使用 Youtube API 和 onBehalfOfContentOwner 的 CMS 频道列表

    我正在使用 Youtube Data API 进行有针对性的查询 就像这个例子 https developers google com youtube analytics v1 reference reports query 对于 MCN
  • Cassandra 备份,包括架构

    我感兴趣的备份技术有两种 a SCHEMA 备份 恢复数据库模式 添加或删除列 更改列类型 添加表等 b 数据备份 恢复数据 更新 从一个表读取到另一个表 让我通过例子来解释一下 首先 我创建实体 客户 Customer 编号 名称 11
  • 数据表:如何将类设置为表行单元格(但不是表头单元格!)

    我的桌子有一个非常漂亮的风格 抱歉 链接不再有效 我必须添加 sClass 以便新行 由 fnAddData 添加 获得正确的类 不幸的是 这破坏了我的布局 因为这些类也被添加到我的表头单元格中 抱歉 链接不再有效 如何配置 sClass
  • 为什么必须为方法引用显式指定类/对象名称?

    当我想引用当前范围内的方法时我仍然需要 指定类名 对于静态方法 或this before 操作员 例如 我需要写 import java util stream Stream public class StreamTest public s
  • 如何使用 Apache PDFBox 从 PDF 中的按钮图标提取图像?

    我想使用 java netbeans 从 pdf 中的按钮获取图像图标 并将其放在某个面板中 然而我在这里碰了砖头 我使用 PDFBox 作为我的 PDF 导出器 但我似乎理解不够 我已经成功地从表单字段中读取内容 但是只要我尝试在 PDF
  • 处理 SFSafariViewController 中的弹出窗口/选项卡

    我正在我的应用程序中实现 SoundCloud 登录流程 应用程序打开https soundcloud com connect in an SFSafariViewController with a redirect uri它使用我的应用程
  • Java 包结构中的模块与层

    我曾经把所有东西都放在这样的包中 com company app module1 com company app module2 但它使得基于包的 AOP 切入点变得困难 并导致需要 IDE 才能理解的巨大包 所以现在我意识到我需要一个更深
  • jqm 弹出窗口未打开

    我向 div 容器添加了一个弹出窗口 打开弹出窗口不起作用 这是我的容器结构 div div div style display none a class select Button a div ul ul div div
  • 为什么 Node.js 是异步的?

    实际上没有人问过这个问题 从我得到的所有 建议 以及我在这里问之前的搜索 那么为什么 Node js 是异步的呢 经过一番研究后我得出的结论是 像 PHP 和 Python 这样的语言是脚本语言 我可能对脚本语言的实际语言是错误的 而 Ja