如何在Promise.all()中识别结果

时间:2017-01-31 14:53:03

标签: javascript node.js promise es6-promise

我正在创建一个基于它收到的配置执行任务的模块。这些任务是异步的,并返回一个承诺。目前只有两个任务需要处理,但是如果还有更多的任务要处理,我将遇到一个问题,即确定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()结算,如何确定哪个值属于哪个承诺?

2 个答案:

答案 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)来创建输出对象。