我正在尝试等待多个回调,但我想不出一种很好的方法。
我的代码是:
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));
};
但是没有用。
答案 0 :(得分: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()
的实现,而不必在这里过多介绍。但是,我提供了一些可以与您显示的代码一起使用的东西。
注意:使用诺言时,最好使您的下层操作有义务,然后使用诺言实现所有控制流和错误处理。通常,它也容易得多(因为Promise特别擅长为您传播错误,而回调则不是)。在代码的更高级别混合使用回调和Promise会很快变得混乱不堪。
答案 1 :(得分:-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);
})
};