当前位置: 首页 > 面试题库 >

Node.js:何时使用Promises vs Callbacks

丁雅逸
2023-03-14
问题内容

我有一些要更新的旧Node.js代码。在此过程中,我正在设计新模块以与旧代码一起使用。我发现现在,与我最初写这篇文章时相反,我更多地依赖使用ES6
Promise,而不是回调。所以现在我混合了一些函数,这些函数返回Promise和一些采用回调-这很乏味。我认为最终应该重构使用诺言。但是在那之前…

在什么情况下首选promise和回调在哪里?

在某种情况下,回调能比承诺更好地处理吗,反之亦然?

根据到目前为止所见,我真的看不出有任何理由使用回调代替promise。真的吗?


问题答案:

首先,您几乎永远都不想编写混合了回调和对异步操作的承诺的代码。如果您要转向承诺或引入一些承诺,那么您可能希望将同一代码段中的回调重构为承诺。对于适当的操作类型,promise与普通回调相比有很多优点,因此当已经在代码区域中工作时,进行转换非常值得。

承诺非常适合:

  • 监视同步操作
  • 只需通知一次(通常是完成或错误)
  • 协调或管理多个异步操作,例如排序或分支异步操作或同时管理飞行中的多个操作
  • 从嵌套或深度嵌套的异步操作传播错误
  • 准备好使用异步/等待的代码(或现在将其与编译器一起使用)
  • 适合Promise模型的操作,其中只有三个状态:pendingfulfilled并且rejected状态从pending => fulfilled或从的状态转换pending => rejected不能更改(单个单向转换)。
  • 动态链接或链接异步操作(例如执行这两个异步操作,检查结果,然后根据中间结果决定要执行哪些其他异步操作)
  • 管理异步和同步操作的混合
  • 自动捕获并向上传播异步完成回调中发生的任何异常(在普通回调中,这些异常有时会被静默隐藏)。

普通的回调对于promise不能做的事情有好处:

  • 同步通知(例如的回调Array.prototype.map()
  • 通知可能会发生多次(因此需要多次调用回调)。承诺是一次性的设备,不能用于重复通知。
  • 无法映射到挂起,已实现,已拒绝的单向状态模型中的情况。

而且,我也将添加EventEmitter

EventEmitters适用于:

  • 发布/订阅类型通知
  • 与事件模型的接口,特别是事件可以多次发生(如流)时
  • 当第三方代码想要参与或监视某事时,而没有eventEmitter的API,则松散的耦合。无需设计API。只需公开一个eventEmitter并定义一些事件以及与之相关的数据即可。

有关将纯回调代码转换为Promises的说明

如果您的回调调用适合与作为最后一个参数传递,并呼吁这样的回调约定的节点callback(err, result),那么你有点自动换行父功能的承诺与util.promisify()在node.js中,或者使用蓝鸟承诺库,用Promise.promisify()

使用Bluebird,您甚至可以一次分配一个完整的模块(在node.js调用约定中使用异步回调),例如:

const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));

fs.writeFileAsync("file.txt", data).then(() => {
    // done here
}).catch(err => {
    // error here
});

在node.js版本8+中

现在有util.promisify()一个将使用node.js异步调用约定的异步函数转换为返回promise的函数。

doc中的示例

const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);

// usage of promisified function
stat('.').then((stats) => {
  // Do something with `stats`
}).catch((error) => {
  // Handle the error.
});


 类似资料:
  • 问题内容: 已锁定 。该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。它目前不接受新的答案或互动。 我对这种东西是陌生的,但是最近我已经听到很多关于Node.js有多出色的信息。考虑到我一般喜欢使用jQuery和JavaScript有多少,我不禁想知道如何决定何时使用Node.js。我想到的Web应用程序有点像Bitly-需要一些内容,然后将其存档。 从过去几天我所做的所有作业中,我获得

  • 我是新手,但最近我听到很多关于Node.js有多好的消息。考虑到总体上我是多么热爱使用jQuery和JavaScript,我不禁想知道如何决定何时使用Node.js。我心目中的web应用程序类似于Bitly-获取一些内容,并将其存档。 从过去几天我一直在做的所有作业中,我获得了以下信息。node.js 是一个命令行工具,可以作为常规web服务器运行,允许运行JavaScript程序 使用great

  • 问题内容: 抱歉,如果我有点模棱两可,但是我试图了解使用Node.js而不是其他服务器端语言的真正优势。 我是JavaScript爱好者,所以我可能会玩Node.js,但我想知道是否应该在项目中使用它。 问题答案: 在V8上发生了异步非阻塞I / O 构建。 因此,我们拥有了Google JavaScript解释器V8的所有性能提升。由于JavaScript性能竞赛尚未结束,您可以期望Google

  • Node.js v22中,WebSocket如何使用? 希望得到代码案例。

  • 问题内容: 我需要下一个流程: nodejs utils api中有这种可能性吗? 问题答案: 您可以使用node-time,如下所示:

  • 问题内容: 场景 :考虑以下是节点Web应用程序的代码部分。 问题 :我正在检查公正或公正哪一个。上面的示例代码对两者的工作原理完全相同,并且在执行方面没有任何区别。 问题 : 有人 可以对此加以说明,何时使用和何时使用以及一些重要的区别吗? 问题答案: 有人总是写是为了确保执行在触发回调后停止。 如果您不这样做,则可能要冒第二次触发回调的风险,这通常会造成灾难性的后果。您的代码可以正常使用,但我