使用async / await + Bluebird来promisifyAll

时间:2017-03-29 14:40:01

标签: node.js asynchronous promise bluebird

我正在构建一个使用async/await的库,我想知道是否可以将fs等原生模块与async/await一起使用。我知道async/await它只是背景中的承诺,所以有一种本地方式来宣传方法或功能吗?目前我正在使用蓝鸟,但我不知道它是不是很糟糕。

示例:

    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吗?

3 个答案:

答案 0 :(得分:7)

  

我正在构建一个使用async / await的库,我想知道是否可以使用ass / 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'),它可以立即让您使用返回promises而不是回调的fs模块版本。结合异步等待,它可以让您执行以下操作:

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

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

上面的代码仍然是无阻塞的。

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

参见示例:

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

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

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

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

我知道异步/等待它只是背景中的Promise,所以......是否有一种本地方式来宣传方法或函数?

很快Node将支持本地 - 请参阅 PR#5020为Promises添加核心支持

但与此同时,您可以使用mz

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

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

更新:上面提到的PR 5020似乎不会很快落入Node中 - 感谢Benjamin Gruenbaum在评论中指出它。所以似乎使用Bluebird的promisifypromisifyAll以及有用的mz模块将是使用Node的核心模块使用该语言的现代功能的唯一简单方法。幸运的是,它们运作良好,所以这不是一个大问题。

答案 1 :(得分:2)

使用Bluebird和Promises只会增加你的头脑。意味着蓝鸟足以处理其他承诺。

由于

答案 2 :(得分:2)

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

Bluebird的承诺根据Promises / A +规范实施then,保证与await一起使用。无论如何,你可以将原生承诺传递给蓝鸟,它会工作得很好。