Bluebird NPM:Bluebird JS Promise 示例
⚡ 智能摘要
Bluebird JS 是一个功能齐全的 Promise 库,用于…… Java该脚本的主要功能是实现 Promise 化:将基于回调的 Node 模块转换为返回 Promise 的模块,从而实现整个库的 Promise 化。 MongoDB 驱动程序可以异步使用。

什么是 Bluebird JS?
Bluebird JS 是一个功能齐全的 Promise 库,用于…… Java脚本最强大的特性在于它允许你“Promisify”其他Node模块,以便异步使用它们。Promisify是应用于回调函数的概念,它确保每个被调用的回调函数都会返回一个值。
所以如果 Node.js 该模块包含一个不返回值的回调函数,承诺该模块会自动修改其中的所有函数,使每个函数都返回一个值。
这意味着你可以使用 Bluebird 来制作 MongoDB 该模块异步运行,这为编写 Node.js 应用程序增加了另一层便利。
下面的示例首先建立与“EmployeeDB”数据库中“Employee”集合的连接。连接建立后,它会检索集合中的所有记录并将其显示在控制台中。
如何使用 Bluebird JS 库生成承诺
以下是使用 Bluebird JS 库生成 Promise 的分步示例。
步骤 1)安装 NPM 模块
要在 Node 应用程序中使用 Bluebird,需要安装 Bluebird 模块。请使用以下命令安装:
npm install bluebird
步骤 2)包含 Bluebird 模块
下一步是将 Bluebird 模块集成到你的代码中,并将整个过程 Promise 化。 MongoDB 模块。这里的“承诺”指的是 Bluebird 确保模块中定义的每个方法都能正常工作。 MongoDB 图书馆返回一个承诺。
Code 说明:
- 此
require该命令包含 Bluebird 库。 - 蓝鸟
.promisifyAll()该方法会为每个方法创建一个异步版本。 MongoDB 模块提供,因此每个模块都在后台运行并返回一个 Promise。
步骤 3)连接到数据库
最后一步是连接到数据库,检索集合中的所有记录,并将它们显示在控制台日志中。
Code 说明:
- 请注意
connectAsync采用的方法代替常规方法。connect方法。Bluebird 附加了 异步 每个方法的后缀 MongoDB 该库用于区分返回 Promise 的调用和不返回 Promise 的调用。没有 Async 后缀的方法不提供此类保证。 - 像
connectAsync,findAsync该方法返回所有记录 MongoDB “员工”集合。 - If
findAsync成功解析后,以下代码块将遍历集合中的每个记录,并将其显示在控制台日志中。
如果正确执行上述步骤,则员工集合中的所有文档将显示在控制台中,如下面的输出所示。
以下是完整的代码,供您参考:
var Promise = require('bluebird'); // promisifyAll adds an Async variant of every MongoDB method var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient; mongoClient.connectAsync('mongodb://localhost/EmployeeDB') .then(function(db) { return db.collection('Employee').findAsync({}); }) .then(function(cursor) { cursor.each(function(err, doc) { console.log(doc); }); });
⚠️驱动程序版本说明: 上述代码的目标 MongoDB Node驱动程序2.x,其中 connect 使用数据库对象进行解析。来自驱动程序 3.0以上 它以一个 MongoClient因此,该链必须调用 client.db('EmployeeDB').collection('Employee') 而不是 db.collection('Employee')现代驱动程序版本也已经返回原生 Promise,这使得 promisifyAll 没有必要 MongoDB 特别。
Bluebird 与 Native Pros:该用哪个?
Bluebird 最初编写时,Node 完全不支持 Promise,因此该库填补了平台的一个真正空白。Node 从版本 4 开始就提供了原生 Promise 支持。 async/await 自 7.6 版本以来,对于今天开始项目的人来说,计算方式发生了很大的变化。
| 方面 | 知更鸟 | 原住民的承诺 |
|---|---|---|
| 依赖 | 一个用于安装和维护的 npm 包 | 内置于运行时中 |
| 承诺回调 | promisifyAll() 转换整个模块 |
util.promisify() 转换一个函数 |
| 额外帮手 | 地图、过滤器、属性、每个、超时、取消 | 所有,全部已解决,任何,仅限种族 |
| 长堆叠 traces | 是的,启用后即可。 | 有所改进,但篇幅更短 |
| 最适合 | 遗留回调库、并发辅助函数 | 新代码,以及任何使用 async/await 的代码 |
对于新工作,请选择原生 Promise,因为它们不需要任何依赖项,并且可以直接与 async/await 集成。如果依赖项仍然只公开回调函数,或者其并发辅助函数(例如)存在问题,则可以使用 Bluebird。 Promise.map 通过设置并发限制,可以节省大量代码。
如何使用 Bluebird Promise 处理错误
上述示例没有故障路径。如果 MongoDB 如果 Promise 链没有运行,或者集合名称错误,则链会失败,并且不会打印任何内容——进程会直接退出,没有任何解释。每个 Promise 链都需要一个终端处理程序。
Bluebird 支持 .catch() 对于拒绝和 .finally() 清理工作必须按顺序进行。它还支持类型化捕获,这种捕获方式可以处理一类错误,同时允许其他类型的错误传播。
var Promise = require('bluebird'); var mongoClient = Promise.promisifyAll(require('mongodb')).MongoClient; var connection; mongoClient.connectAsync('mongodb://localhost/EmployeeDB') .then(function(db) { connection = db; return db.collection('Employee').findAsync({}); }) .then(function(cursor) { return cursor.toArrayAsync(); }) .then(function(docs) { docs.forEach(function(doc) { console.log(doc); }); }) .catch(Promise.TimeoutError, function(err) { console.error('The database did not respond in time.'); }) .catch(function(err) { // Any other rejection from any step above arrives here console.error('Query failed:', err.message); }) .finally(function() { // Runs on success and on failure, so the socket always closes if (connection) { connection.close(); } });
这里有三个习惯很重要。首先,地点 .catch() 在最后而不是每一步之后,因为一个终端处理程序会接收来自链中每个先前环节的拒绝。其次,使用 .finally() 用于释放数据库连接等资源,因为它在成功和失败路径上都会运行。第三,切勿让链式调用没有捕获机制:在当前版本中,未处理的拒绝会终止 Node 进程,而 Bluebird 会事先打印明确的警告。启用长栈 trac在开发过程中使用 Promise.config({ longStackTraces: true }) 这使得查找拒绝的根源变得更加容易。
Bluebird Promisify 常见错误及修复方法
大多数 Bluebird 问题都源于 Promise 化的命名约定,或在同一调用链中混用回调和 Promise 调用方式,而非库本身存在缺陷。以下每个症状都列出了其原因和解决方法。
- “connectAsync 不是一个函数”: 该模块是直接需要的,而不是通过其他方式引入的。
promisifyAll()因此,不存在异步变体。请按上述方式包装 require 调用。 - 调用普通方法却得到 undefined:
connect()仍然需要一个回调函数。只有带有 Async 后缀的版本才会返回一个 Promise。 - 向异步方法传递回调函数: 既不提供回调函数,也不提供回调函数。
await并且该 Promise 未被观察到就已解决。每次调用只能使用一种样式,不能同时使用两种样式。 - 在已基于 Promise 的库中使用 promisifyAll: 虽然无害但毫无意义,而且会生成容易混淆的双后缀名称。请先查看库文档。
- 悄无声息地丢失错误: 一条没有链子
.catch()直到 Node 报告未处理的拒绝并退出之前,都会隐藏拒绝原因。即使在短脚本中,也务必使用 catch 语句终止链式调用。



