【问题标题】:Combining promises into promise.all将 promise 组合成 promise.all
【发布时间】:2019-11-27 00:16:18
【问题描述】:

对于 id 列表,我想做一些 GET。这些都包含在一个承诺中。

let ids = [1, 2, 3]
let promises = [];
for (id in ids) {
    promises.push(ApiService.get(url + id))
}
return promises

现在在结果上调用 promises.all 时,结果按创建它们的顺序排列 (1, 2, 3)。由于这发生在某种 API 控制器中,我宁愿不必将“ids”与承诺一起返回。而是返回一些:

{1: PromiseofId1, 2: PromiseofId2, 3:PromiseofId3}

也许我的思维方式有缺陷,我愿意接受建议。

【问题讨论】:

  • 当我看到一个数组和for ... in 一起使用时,我起鸡皮疙瘩。
  • @ASDFGerte 为什么?
  • Promise.all() 使用数组。使用数组index.. 最佳做法是构建 API,以便无论返回什么,都可以识别它是什么,因此顺序并不重要,知道客户端上的内容是什么。
  • @Gibor 他的例子中的数组可能是["lalala", null, undefined],它不会改变任何事情。此外,如果有人想到将可枚举属性添加到 Array.prototype,事情就会变得非常糟糕。
  • @Gibor 除了在原型上包含枚举值外,for ... in 的规范也不需要按顺序循环。这取决于浏览器的编码方式。大多数浏览器都会这样做,但这不能保证。因此,在数组的情况下,不能 100% 确定数组元素 [0] 将首先被处理,这可能导致难以找到错误。正常的for ( let i = .... 循环和array.forEach() 没有这个问题。有关详细信息,请参阅 MDN 文档。

标签: javascript promise


【解决方案1】:

由于您知道顺序,因此您可以在之后重新关联它们。

let ids = [1, 2, 3]
let promises = [];
for (id in ids) {
    promises.push(ApiService.get(url + id))
}
Promise.all(promises).then(results => {
    const data = {};
    results.forEach( (value, index) => { data[ ids[index] ] = value } );
    return data;
});

【讨论】:

  • Albertos 的评论也是正确的,选择这个是为了团队的可读性。
【解决方案2】:

您可以使用reduce 构建一个将每个id 映射到Promise 对象的对象。看这个例子,它有字符串而不是 Promises,所以你可以通过运行 sn-p 来查看输出:

let ids = [1, 2, 3]
let promises = ids.reduce((acc, cur) => ({ ...acc, [cur]: `ApiService${cur}`}), {});

console.log(promises);

在你的情况下,你可以这样:

let ids = [1, 2, 3]
let promises = ids.reduce((acc, cur) => ({ ...acc, [cur]: ApiService.get(url + id)}), {});

【讨论】:

    【解决方案3】:

    你可能想要这样的东西。

    async function getData(){
      const ids = [1, 2, 3]
      const promises = ids.map(id => ApiService.get(url + id))
      const responses = await Promise.all(promises)
      // Read whatever data from the response
      return responses.reduce((accumulator, response, index) => {
        accumulator[index + 1] = response.data
      }, {})
    }
    
    // Call it from an async function like this.
    const dataMap = await getData()
    // Returns {1:data1, 2:data2, ... }
    

    【讨论】:

      猜你喜欢
      • 2014-11-07
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-23
      • 1970-01-01
      • 2018-02-06
      相关资源
      最近更新 更多