使用 async/await + Bluebird 来 promisifyAll

Using async/await + Bluebird to promisifyAll

我正在构建一个使用 async/await 的库,我想知道是否可以将 fs 等原生模块与 async/await 一起使用。我知道 async/await 它只是后台的 Promises,那么有没有原生的方法来 promisify 一个方法或函数?目前我正在使用 Bluebird,但我不知道它是否是一个坏模式。

示例:

    const Bluebird = require("bluebird");
    const { access } = require("fs");

    const accessAsync = Bluebird.promisify(access);

    async function checkInput(options) {
      await accessAsync(options.file);
      /// etc
      return options;
    }

    module.exports = (options) => {
      Promise.resolve(options)
        .then(checkInput)
    };

我正在结合本机 Promises 和 Bluebird。我应该只使用 Bluebird 吗?

使用 Bluebird 和 Promises 只会增加您的开销。这意味着 Bluebird 足以处理其他承诺。

I'm constructing a library that uses async/await, and I would like to know if it is possible to use native modules like fs with the async/await.

是的。你可以用 Bluebird 比你的例子更简单:

let fs = Promise.promisifyAll(require('fs'));

// and in async function:
let contents = await fs.readFileAsync('file.txt', 'utf-8');

注意需要在方法名末尾加上Async

或者您可以使用 mz 模块,而无需在方法中添加 Async。参见:

一旦您 npm install mz 就可以需要许多模块 - 例如您可以 require('mz/fs') 它立即让您使用 fs 模块版本 return s 承诺而不是接受回调。结合 async await 它可以让你做这样的事情:

let fs = require('mz/fs');

// and in async function:
let contents = await fs.readFile('file.txt', 'utf-8');

以上代码仍然是非阻塞的。

请参阅此答案,其中我展示了 crypto 模块的 mz 版本的示例并对其进行了更详细的解释:

  • Which functions could work as synchronous in node.js?

参见示例:

let crypto = require('mz/crypto');

async function x() {
  let bytes = await crypto.randomBytes(4);
  console.log(bytes);
}

您可以对许多其他模块执行相同的操作,包括:

  • child_process
  • crypto
  • dns
  • fs
  • readline
  • zlib

I know that async/await it's just Promises in the background, so... is there a native way to promisify a method or function?

很快 Node.js 将原生支持 - 请参阅 PR #5020 添加对 Promises 的核心支持:

但同时您可以使用 mz

有关更多上下文,另请参阅 问题 #7549 v1:执行不带回调的异步函数应该 return promises:

另请参阅 Node.js 的 Promises 工作组存储库

更新: 上面提到的 PR 5020 似乎不会很快登陆 Node.js - 感谢 。因此,使用 Bluebird 的 promisifypromisifyAll 以及有用的 mz 模块似乎是将语言的现代特性与 Node.js 的核心模块一起使用的唯一简单方法。幸好他们工作得很好,所以这不是什么大问题。

无论如何,Bluebird 是设计 以使用本机 promise。您描述的用例不仅得到支持 - 而且是 Bluebird 的设计目标。

Bluebird 的承诺根据 Promises/A+ 规范实现 then,保证与 await 一起工作。此外,您可以将本机承诺传递给 Bluebird,它会正常工作。