节点回调承诺使用async/await

Sen*_*eca 7 javascript node.js async-await es6-promise

我正在尝试编写一个将节点式回调函数转换为promises的简单函数,因此我可以将它们与async/await一起使用.

当前代码:

function toPromise(ctx, func, ...args) {
  let newPromise;

  args.push((err, res) => {
    newPromise = new Promise((resolve, reject)=> {
       if(err) reject(err);
       else{
        resolve(res) 
      };
     });
    });

   func.apply(ctx, args);

   return newPromise;
}
Run Code Online (Sandbox Code Playgroud)

示例用法:

const match = await toPromise(user, user.comparePassword, password);
//trying to avoid the following:
user.comparePassword(password, (err, res) => {
     ... });
Run Code Online (Sandbox Code Playgroud)

对于一些很棒的库来说,这可能没有任何意义,但我只是想把它编写为一个练习.

问题当然是匹配评估为未定义,显然在await语法行之后,promise得到解决.

知道如何解决这个问题吗?

tsm*_*tsm 10

从节点v8.0.0开始,他们添加了util.promisify.

const util = require('util');
const fs = require('fs');

const stat = util.promisify(fs.stat);
stat('.').then((stats) => {
  // Do something with `stats`
}).catch((error) => {
  // Handle the error.
});
Run Code Online (Sandbox Code Playgroud)

参考:https://nodejs.org/api/util.html#util_util_promisify_original


Ber*_*rgi 4

您的问题是您正在构造newPromise异步回调的内部。所以当你退货时你仍然有。undefined相反,您需要Promise立即调用构造函数,并且仅将resolve/放入reject异步回调中:

function toPromise(ctx, func, ...args) {
    return new Promise((resolve, reject) => {
        args.push((err, res) => {
            if (err) reject(err);
            else resolve(res);
        });
        func.apply(ctx, args);
    });
}
Run Code Online (Sandbox Code Playgroud)

另请参阅如何将现有回调 API 转换为 Promise?