使用nodejs解决各种各样的问题(开发人员常犯的)
使用nodejs解决各种各样的问题(开发人员常犯的)
2024-11-22 06:56:59  作者:扭曲的灵魂  网址:https://m.xinb2b.cn/tech/wxg343904.html

自从 Node.js 面世以来,它就受到了相当多的赞扬和批评。辩论仍在继续,可能不会很快结束。在这些辩论中,我们经常忽略的是,每种编程语言和平台都会基于某些问题受到批评,这些问题是由我们使用平台的方式造成的。

不管 Node.js 让编写安全代码多么困难,以及编写高并发代码多么容易,该平台已经存在了很长一段时间,并已被用于构建大量强大而复杂的 Web 服务。这些 Web 服务可以很好地扩展,并通过它们在 Internet 上的持久性证明了它们的稳定性。

但是,与任何其他平台一样,Node.js 容易受到开发人员问题的影响。其中一些错误会降低性能,而另一些错误会使 Node.js 看起来无法用于您想要实现的任何目标。在本文中,我们将看看 Node.js 新手经常犯的十个常见错误,以及如何避免这些错误成为 Node.js 专业人士。

错误 #1:阻塞事件循环

Node.js 中的 JavaScript(就像在浏览器中一样)提供了单线程环境。这意味着您的应用程序没有两个部分是并行运行的。相反,并发是通过异步处理 I/O 绑定操作来实现的。例如,从 Node.js 到数据库引擎的请求以获取一些文档是允许 Node.js 专注于应用程序的其他部分的原因:



然而,在连接了数千个客户端的 Node.js 实例中,一段受 CPU 限制的代码就足以阻止事件循环,让所有客户端等待。受 CPU 限制的代码包括尝试对大型数组进行排序、运行极长的循环等等。例如:


如果在一个小的“users”数组上运行,调用这个“sortUsersByAge”函数可能没问题,但是对于一个大数组,它会对整体性能产生可怕的影响。如果这是绝对必须完成的事情,并且您确定在事件循环中不会有任何其他等待(例如,如果这是您使用 Node.js 构建的命令行工具的一部分,并且它如果整个事情同步运行都没有关系),那么这可能不是问题。但是,在尝试一次为数千名用户提供服务的 Node.js 服务器实例中,这种模式可能是致命的。

如果从数据库中检索此用户数组,理想的解决方案是直接从数据库中获取已排序的用户。如果事件循环被编写用于计算长期金融交易数据历史总和的循环阻塞,则可以将其推迟到某些外部工作者/队列设置,以避免占用事件循环。

如您所见,对于此类 Node.js 问题没有灵丹妙药的解决方案,而是需要单独解决每种情况。基本思想是不在前端的 Node.js 实例中进行 CPU 密集型工作——客户端同时连接的那些。

错误 #2:多次调用回调

JavaScript 一直依赖回调。在 Web 浏览器中,事件是通过传递对(通常是匿名的)函数的引用来处理的,这些函数的作用类似于回调。在 Node.js 中,回调曾经是代码中异步元素相互通信的唯一方式——直到引入了 Promise。回调仍在使用中,包开发人员仍然围绕回调设计他们的 API。与使用回调相关的一个常见 Node.js 问题是多次调用它们。通常,包提供的用于异步执行某些操作的函数被设计为期望函数作为其最后一个参数,该参数在异步任务完成时调用:


注意每次调用“done”时都有一个返回语句,直到最后一次。这是因为调用回调不会自动结束当前函数的执行。如果第一个“return”被注释掉,传递一个非字符串密码给这个函数仍然会导致“computeHash”被调用。根据“computeHash”如何处理这种情况,“done”可能会被多次调用。当他们传递的回调被多次调用时,从其他地方使用此函数的任何人都可能完全措手不及。

小心是避免此 Node.js 错误所需要的一切。一些 Node.js 开发人员习惯于在每次回调调用之前添加一个 return 关键字:


在很多异步函数中,返回值几乎没有任何意义,所以这种方法往往可以很容易地避免这样的问题。

错误 #3:深度嵌套回调

深度嵌套的回调,通常被称为“回调地狱”,它本身并不是 Node.js 的问题。但是,这可能会导致代码快速失控的问题:



任务越复杂,情况就越糟糕。通过以这种方式嵌套回调,我们很容易以容易出错、难以阅读和难以维护的代码告终。一种解决方法是将这些任务声明为小函数,然后将它们链接起来。虽然,(可以说)最干净的解决方案之一是使用处理异步 JavaScript 模式的实用程序 Node.js 包,例如Async.js:


与“async.waterfall”类似,Async.js 还提供了许多其他函数来处理不同的异步模式。为简洁起见,我们在这里使用了更简单的示例,但实际情况往往更糟。

错误 #4:期望回调同步运行

带有回调的异步编程可能不是 JavaScript 和 Node.js 独有的东西,但它们是其流行的原因。对于其他编程语言,我们习惯于可预测的执行顺序,两条语句将一个接一个地执行,除非有特定的指令在语句之间跳转。即使这样,这些通常也仅限于条件语句、循环语句和函数调用。

但是,在 JavaScript 中,使用回调,特定函数可能无法正常运行,直到它等待的任务完成。当前函数的执行将一直运行到最后,没有任何停止:


您会注意到,调用“testTimeout”函数将首先打印“Begin”,然后打印“Waiting..”,然后是“Done!”消息。大约一秒钟后。

触发回调后需要发生的任何事情都需要从其中调用。

错误#5:分配给“exports”,而不是“module.exports”

Node.js 将每个文件视为一个小的独立模块。如果你的包有两个文件,可能是“a.js”和“b.js”,那么为了让“b.js”访问“a.js”的功能,“a.js”必须通过添加属性来导出它出口对象:


完成后,任何需要“a.js”的人都将获得一个具有属性函数“verifyPassword”的对象:


但是,如果我们想直接导出这个函数,而不是作为某个对象的属性呢?我们可以覆盖导出来执行此操作,但我们不能将其视为全局变量:


请注意我们如何将“导出”视为模块对象的属性。这里“module.exports”和“exports”之间的区别非常重要,并且经常是新 Node.js 开发人员感到沮丧的原因。

错误 #6:从内部回调中抛出错误

JavaScript 有异常的概念。模仿几乎所有支持异常处理的传统语言的语法,例如 Java 和 C ,JavaScript 可以在 try-catch 块中“抛出”和捕获异常:


但是,try-catch 在异步情况下不会像您期望的那样运行。例如,如果你想用一个大的 try-catch 块来保护一大块具有大量异步活动的代码,它不一定有效:


如果对“db.User.get”的回调异步触发,那么包含 try-catch 块的作用域早就脱离了上下文,它仍然能够捕获从回调内部抛出的错误。

这就是在 Node.js 中以不同方式处理错误的方式,这使得在所有回调函数参数上遵循 (err, ...) 模式至关重要——如果发生错误,所有回调的第一个参数都应该是一个错误.

错误 #7:假设 Number 是整数数据类型

JavaScript 中的数字是浮点数——没有整数数据类型。您不会认为这是一个问题,因为不会经常遇到大到足以强调浮动限制的数字。这正是与此相关的错误发生的时候。由于浮点数只能将整数表示形式保存到某个值,因此在任何计算中超过该值都会立即开始搞砸。尽管看起来很奇怪,但以下在 Node.js 中的计算结果为 true:


不幸的是,JavaScript 中数字的怪癖并没有就此结束。即使数字是浮点数,也适用于整数数据类型的运算符:


然而,与算术运算符不同的是,位运算符和移位运算符仅适用于此类大“整数”数字的尾随 32 位。例如,尝试将“Math.pow(2, 53)”移动 1 将始终计算为 0。尝试对相同的大数进行按位或 1 将计算为 1。


您可能很少需要处理大数,但如果您这样做,有很多大整数库可以实现对大精度数的重要数学运算,例如node-bigint。

错误 #8:忽略流式 API 的优势

假设我们想要构建一个类似代理的小型 Web 服务器,通过从另一个 Web 服务器获取内容来响应请求。例如,我们将构建一个服务 Gravatar 图像的小型 Web 服务器:


在这个 Node.js 问题的特定示例中,我们从 Gravatar 获取图像,将其读入缓冲区,然后响应请求。考虑到 Gravatar 图像不是太大,这并不是一件坏事。但是,想象一下,如果我们代理的内容大小是数千兆字节。更好的方法是:


在这里,我们获取图像并简单地将响应传递给客户端。在任何时候我们都不需要在提供之前将整个内容读入缓冲区。

错误 #9:使用 Console.log 进行调试

在 Node.js 中,“console.log”允许您将几乎所有内容打印到控制台。将对象传递给它,它会将其打印为 JavaScript 对象字面量。它接受任意数量的参数,并以空格分隔的方式打印它们。开发人员可能会想用它来调试他的代码有很多原因;但是,强烈建议您在实际代码中避免使用“console.log”。您应该避免在整个代码中编写“console.log”来调试它,然后在不再需要它们时将它们注释掉。相反,请使用专门为此构建的令人惊叹的库之一,例如debug。

此类软件包提供了在启动应用程序时启用和禁用某些调试行的便捷方法。例如,使用调试,可以通过不设置 DEBUG 环境变量来防止任何调试行被打印到终端。使用它很简单:


要启用调试行,只需在环境变量 DEBUG 设置为“app”或“*”的情况下运行此代码:



  • 会发光的植物大多属于哪一种植物(科学家创造出会发光的植物)
  • 2024-11-22科学家创造出会发光的植物我们梦想中闪闪发光的温室距离我们仍然很遥远,但现在有了点吸引人的进展了科学家们研发出了一种新植物,它一生都能靠自己持续发光这是在之前发光植物基础上的惊人进步,比之前进行基因改造的烟草要更亮,也不需要添。
  • 简单大气有寓意的好名字(取名有道好听又有内涵的名字)
  • 2024-11-22取名有道好听又有内涵的名字自古以来,流传着这样的俗语:“赐子千金,不如教子一艺;教子一艺,不如赐子一名”名字不仅体现了长辈的美好期许,更可以给人更深刻的第一印象尤其在互联网时代,很多时候都是“先见其名,再见其人”一个好名字,无。
  • 杨广的妃子都是什么下场(隋唐英雄杨广的妃子)
  • 2024-11-22隋唐英雄杨广的妃子杨广的妃子,杨广的妃子们1、萧皇后,西梁明帝萧岿之女隋炀帝愍皇后萧氏(567~647年),南兰陵(今常州武进市)人隋朝时期女性历史人物,梁武帝萧衍后代,西梁孝明帝萧岿之女,母为张皇后2、萧嫔,赵王杲母。
  • 老版水浒传各个角色回忆(从水浒传这八大主演)
  • 2024-11-22从水浒传这八大主演文/主任对于央视版水浒传和新版水浒传到底哪个版本更接近原著,更能展现梁山108将的本色,故事讲得更为精彩,观众的好评度更好,其实每个人心里都有自己的一本账总体看来,更多人会认为央视版水浒传拍得更好,这。
  • 罗马帝国与文艺复兴的关系(罗马帝国的基督化)
  • 2024-11-22罗马帝国的基督化基督教也许被人视为乌合之众对这个世界的复仇公元70年耶路撒冷所罗门圣殿的毁灭造成了“犹太人大流散”,他们所怀揣的犹太末世论种子在将来会蜕变为基督教这些思想的种子起先在远离罗马的地方生根发芽,而我们此前。
  • c1驾照能开哪些客车(c1驾照可以开的车型汇总)
  • 2024-11-22c1驾照可以开的车型汇总C1可驾驶车辆为小型、微型载客汽车以及轻型、微型载货汽车;轻、小、微型专项作业车9座以下的小型客车,设计最大总质量小于等于4500kg长≤6.0m宽≤2.0m高≤2.5m迈巴赫加长版的林肯、悍马等车型。
  • qq怎么引流最快最有效 一天引流100人是怎么做到的
  • 2024-11-22qq怎么引流最快最有效 一天引流100人是怎么做到的流量是生意的本质,没有流量,产品再好也没有用,所以,不管是对于个人创业者,还是企业,能快速低成本地获取更多的流量客源,才是赚钱的关键所在qq群营销,是目前成本相对较低,且更容易看到效果的一种引流方式,。
  • 一个黑一个今是什么字(一个黑一个今是啥字)
  • 2024-11-22一个黑一个今是啥字一个黑一个今是:黔黔,拼音qián意思是黑色,也是中国贵州省的别称黔,形声字从黑,从今,今亦声作名词时指百姓如:黔庶(百姓,平民);黔细(黔首和细民的别称);黔落(百姓所居的村落);黔愚(无知的百姓)。
  • 吃完香蕉可以喝牛奶吗(牛奶香蕉能一起吃吗)
  • 2024-11-22牛奶香蕉能一起吃吗吃完香蕉可以喝牛奶香蕉、牛奶一起吃是可以的牛奶是常见的饮品,含有钙、铁、磷、锌、矿物质、蛋白质等丰富的营养,香蕉是常见的水果,含有大量的膳食纤维和微量元素,两者一起吃可以为人体提供充足的优质蛋白、糖分。
  • 新年国潮风画展(新生活新风尚新年画)
  • 2024-11-22新生活新风尚新年画《吉日》推荐单位:中国美协(内蒙古)作者:戴培诚《龙腾鱼跃歌盛世》推荐单位:中国美协(山东)作者:赵庆玲《金土地金娃娃》推荐单位:中国美协(吉林)作者:宋磊《幸福映象》推荐单位:中国美协(山东)作者:。
  • 贵州酸汤的做法(贵州酸汤的七种制作方法)
  • 2024-11-22贵州酸汤的七种制作方法贵州酸汤鱼是一道菜品,制作原料主要有鲜活鱼、番茄、白醋等,美味可口,一种酸酸的感觉汁浓味鲜,鱼肉细嫩,民族风味因其口感独特深受贵州人民的喜爱今天为大家介绍一下贵州酸汤,以供大家参考贵州酸汤的起源▼顾名。
  • 模拟城市4界面(模拟城市4如何设置中文)
  • 2024-11-22模拟城市4如何设置中文打开文件夹,运行SC4-UNINST.EXE把那个SimCity4文件夹里有一个名为English的文件夹,将它重命名为English.oid还有一个名为TChinese的文件夹,将它重命名为Engl。