如何在Node js中等待多个回调

问题描述 投票:0回答:2

我正在尝试等待多次回调,但我无法找到一种方法来做得很好。

我的代码是:

module.exports.getFilledOnlineFormsOfArray = (formIDs, callback) => {
let forms = [];
for (let i = 0; i < formIDs.length; i++) {
    this.getFilledOnlineFormByID(formIDs[i], (err, filledForm) => {
        if (err) callback(err);
        else forms.push(filledForm);
    });
}
callback(null, forms);
};

callback(null, forms)(IE getFilledOnlineFormByID)的每次回调解决后,我如何调用(err, filledForm)

我想出了一个写作的解决方案:

module.exports.getFilledOnlineFormsOfArray = (formIDs, callback) => {
    let forms = [];
    let count = formIDs.length;
    for (let i = 0; i < formIDs.length; i++) {
        this.getFilledOnlineFormByID(formIDs[i], (err, filledForm) => {
            if (err) callback(err);
            else forms.push(filledForm);
            count--;
            if (count === 0)
                callback(null, forms);
        });
    }
};

但用这种方式编码感觉很糟糕。我相信这个问题有更优雅的解决方案。我在互联网上寻找答案,但我发现的是如何将其转换为异步函数,而我现在无法在我的项目中完成。

编辑:我试图像这样使用Promise.all

module.exports.getFilledOnlineFormsOfArray = (formIDs, callback) => {
    let forms = [];
    let async = [];
    for (let i = 0; i < formIDs.length; i++) {
        async.push(this.getFilledOnlineFormByID(formIDs[i], (err, filledForm) => {
        if (err) callback(err);
        else forms.push(filledForm);
       }));
    }
    Promise.all(async).then(callback(null, forms));
};

但它不起作用。

javascript node.js asynchronous callback
2个回答
1
投票

如果您希望所有这些操作并行运行,您可以宣传您的异步操作,然后使用Promise.all()跟踪它们何时完成:

const util = require('util');

module.exports.getFilledOnlineFormsOfArray = (formIDs, callback) => {
    // make a promisified version of the method
    if (!this.getFilledOnlineFormByIDPromise) {
        this.getFilledOnlineFormByIDPromise = util.promisify(this.getFilledOnlineFormByID);
    }

    // use Promise.all() to track when all the promises have completed
    Promise.all(formIDs.map(id => {
        return this.getFilledOnlineFormByIDPromise(id);
    })).then(results => {
        callback(null, results);
    }).catch(err => {
        callback(err);
    });    
};

就个人而言,我会改变getFilledOnlineFormsOfArray()的接口,只返回一个promise并停止使用回调来管理异步操作。你也可以在源头修复this.getFilledOnlineFormByID()的实现,而不是在这里宣传它。但是,我提供了一些可以与您展示的代码一起使用的东西。

注意:使用promises时,最好先实现较低级别的操作,然后使用promises实现所有控制流和错误处理。它通常也容易得多(因为promises特别擅长为你传播错误,而回调则不然)。在更高级别的代码中混合回调和承诺可能会很快变得混乱。


-1
投票

我们可以使用async.parallel来运行多任务列表。

const async = require('async');

 module.exports.getFilledOnlineFormsOfArray = (formIDs, callback) => {
  let taskList = [];
  let forms = [];
  for (let i = 0; i < formIDs.length; i++) {
    taskList.push(function(cb){
      this.getFilledOnlineFormByID(formIDs[i], (err, filledForm) => {
          forms.push(filledForm);
          cb(err, filledForm)
       });
    });
  }
  async.parallel(taskList, function (errs, results) {
    if (errs) {
        console.log(errs);
    }
    console.log('Task list done.', results);
  })
};
© www.soinside.com 2019 - 2024. All rights reserved.