Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
431 views
in Technique[技术] by (71.8m points)

node.js - Using async/await + Bluebird to promisifyAll

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. I know that async/await it's just Promises in the background, so is there a native way to promisify a method or function? Currently I'm using the Bluebird, but I don't know if it's a bad pattern.

Example:

    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)
    };

I'm combining both native Promises and Bluebird. Should I only use Bluebird?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

Yes. You can do it even simpler with Bluebird than in your example:

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

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

Note that you need to add Async at the end of the method names.

Or you can use the mz module, without needing to add Async to the methods. See:

There are many modules that you can require once you npm install mz - for example you can require('mz/fs') and it instantly lets you use the fs module version that returns promises instead of taking callbacks. Combined with async await it lets you do things like:

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

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

The above code is still non-blocking.

See this answer where I show an example of mz version of the crypto module and explain it in more detail:

See example:

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

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

You can do the same with many other modules, including:

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

Soon Node.js will support that natively - see PR #5020 Adding Core support for Promises:

but in the meantime you can use mz.

For more context see also the Issue #7549 v1: executing async functions without callbacks should return promises:

See also the Node.js's Promises Working Group Repository:

Update: It seems that the PR 5020 mentioned above is not going to land in Node.js any time soon - thanks to Benjamin Gruenbaum for pointing it out in the comments. So it seems that using Bluebird's promisify and promisifyAll and the helpful mz module will be the only easy way to use modern features of the language with the core modules of Node.js. Fortunately they work very well, so it's not a big problem.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...