【问题标题】:How to identify results in Promise.all()如何在 Promise.all() 中识别结果
【发布时间】:2017-06-17 01:37:02
【问题描述】:

我正在创建一个模块,该模块根据它收到的配置执行任务。这些任务是异步的并且正在返回一个承诺。目前只有两个任务要处理,但如果还有更多,我会遇到识别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() 解析,我如何识别哪个值属于哪个承诺?

【问题讨论】:

  • 你可以看看Bluebird,它有很方便的方法来处理你的案子

标签: javascript node.js promise es6-promise


【解决方案1】:

Promise.all 解析为一个值数组,其中数组中每个值的索引与传递给生成该值的Promise.all 的原始数组中的 Promise 的索引相同。

如果您需要更花哨的东西,您需要自己跟踪或使用其他提供此类功能的库(如 Bluebird)。

【讨论】:

  • bluebird 的Promise.join() 是我所看到的方式,当我能够接受答案时:)
【解决方案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) 来创建promise 的输入数组,并再次使用Object.keys(config) 来创建输出对象。

【讨论】:

  • 现在接受这个,因为它是一个不需要任何其他库的实际解决方案。这更像是我在思考“必须有更漂亮的方式”时想到的东西,谢谢你的洞察力
猜你喜欢
  • 1970-01-01
  • 2016-01-12
  • 2016-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多