【问题标题】:Using async/await + Bluebird to promisifyAll使用 async/await + Bluebird 来 promisifyAll
【发布时间】:2017-08-23 03:08:41
【问题描述】:

我正在构建一个使用async/await 的库,我想知道是否可以将fs 之类的本机模块与async/await 一起使用。我知道 async/await 它只是在后台 Promise,那么有没有一种原生的方式来承诺一个方法或函数?目前我正在使用 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 吗?

【问题讨论】:

    标签: node.js asynchronous promise bluebird


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我正在构建一个使用 async/await 的库,我想知道是否可以将 fs 等原生模块与 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 模块版本,它返回承诺而不是接受回调。与 async await 结合使用,您可以执行以下操作:

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

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

      查看这个答案,其中我展示了crypto 模块的mz 版本的示例并更详细地解释它:

      查看示例:

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

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

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

      我知道 async/await 只是后台的 Promise,所以……有没有一种原生的方式来 Promisify 方法或函数?

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

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

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

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

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

      【讨论】:

      • 好主意!
      • 我讨厌成为派对的大便者 - #5020 不会很快发生。我创立了 promises 工作组——遗憾的是——由于涉及的工作量很大,目前它不会去任何地方。 util.awaitable 有可能在未来几个月内登陆。
      • @BenjaminGruenbaum 感谢您提供信息。我更新了答案。
      • @celoxxx 查看我的更新答案。我添加了有关 Bluebird 的更多信息以及向 Node 添加承诺支持的拉取请求状态。
      【解决方案3】:

      无论如何,Bluebird设计是为了与原生 Promise 一起工作。您描述的用例不仅受支持,而且是 Bluebird 的设计目标。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-03
        • 2015-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-07
        • 1970-01-01
        • 2018-06-04
        相关资源
        最近更新 更多