Javascript 使用async/await进行承诺的节点回调

Javascript 使用async/await进行承诺的节点回调,javascript,node.js,async-await,es6-promise,Javascript,Node.js,Async Await,Es6 Promise,我正在尝试编写一个简单的函数,将节点样式的回调函数转换为承诺函数,这样我就可以将它们与async/await一起使用 当前代码: function toPromise(ctx, func, ...args) { let newPromise; args.push((err, res) => { newPromise = new Promise((resolve, reject)=> { if(err) reject(err); else{

我正在尝试编写一个简单的函数,将节点样式的回调函数转换为承诺函数,这样我就可以将它们与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;
}
用法示例:

const match = await toPromise(user, user.comparePassword, password);
//trying to avoid the following:
user.comparePassword(password, (err, res) => {
     ... });
对于一些优秀的库来说,这可能没有任何意义,但我只是想把它作为一个练习来编写

问题当然是match的计算结果是未定义的,显然,在wait语法行之后,promise得到了解决


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

你的问题是你正在异步回调内部构造
newPromise
。所以当你还它的时候。相反,您需要立即调用
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);
    });
}

另请参见自节点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.
});
参考: