我正在创建一个基于它收到的配置执行任务的模块。这些任务是异步的,并返回一个承诺。目前只有两个任务需要处理,但是如果还有更多的任务要处理,我将遇到一个问题,即确定Promise.all()
的哪个结果属于哪个任务。
以下是我当前代码的快照:
let asyncTasks = [];
let result = {};
if (config.task0) {
asyncTasks.push(task0(param));
}
if (config.task1) {
asyncTasks.push(task1(param));
}
Promise.all(asyncTasks)
.then(results => {
// TODO: There has to be a prettier way to do this..
if (config.task0) {
result.task0 = results[0];
result.task1 = config.task1 ? results[1] : {};
} else if (config.task1) {
result.task0 = {};
result.task1 = results[0];
} else {
result.task0 = {};
result.task1 = {};
}
this.sendResult(result)
});
配置如下所示:
const config = {
task0: true,
task1: true
};
正如代码中所提到的,必须有一种更漂亮,更可扩展的方法来识别哪个结果来自哪个任务,但我找不到任何有关Promise.all()
的内容可以帮助解决这个问题。
如果Promise.all()
结算,如何确定哪个值属于哪个承诺?
答案 0 :(得分:7)
Promise.all
使用一组值进行解析,其中数组中的每个值的索引与传递给生成该值的Promise.all
的原始数组中的Promise的索引相同
如果您需要更多花哨的东西,您需要自己跟踪它或使用另一个提供此类功能的库(如Bluebird)。
答案 1 :(得分:2)
除了Promise.all
之外,确实没有必要使用任何其他内容。你遇到了困难,因为你的程序的其他结构(config
,以及配置键到函数的任意链接)非常混乱。您可能想要考虑完全重构代码
const config = {
task0: true,
task1: true,
task2: false
}
// tasks share same keys as config variables
const tasks = {
task0: function(...) { ... },
task1: function(...) { ... },
task2: function(...) { ... }
}
// tasks to run per config specification
let asyncTasks = Object.keys(config).map(prop =>
config[prop] ? tasks[prop] : Promise.resolve(null))
// normal Promise.all call
// map/reduce results to a single object
Promise.all(asyncTasks)
.then(results => {
return Object.keys(config).reduce((acc, task, i) => {
if (config[task])
return Object.assign(acc, { [prop]: results[i] })
else
return Object.assign(acc, { [prop]: {} })
}, {})
})
// => Promise({
// task0: <task0 result>,
// task1: <task1 result>,
// task2: {}
// })
注意:我们可以依赖results
的顺序,因为我们使用Object.keys(config)
来创建promises的输入数组,再次使用Object.keys(config)
来创建输出对象。