首页 文章

节点回调承诺使用async / await

提问于
浏览
6

我正在尝试编写一个将节点式回调函数转换为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;
}

示例用法:

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

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

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

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

2 回答

  • 3

    您的问题是您正在构建异步回调内部的 newPromise . 你回来的话就是you've still got 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);
        });
    }
    

    另见How do I convert an existing callback API to promises?

  • 8

    从节点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.
    });
    

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

相关问题