【问题标题】:How to supply metadata about the promises when calling Promise.all()?调用 Promise.all() 时如何提供有关承诺的元数据?
【发布时间】:2021-11-15 17:27:38
【问题描述】:

我正在编写一些如下所示的 Javascript 代码:

const arrayOfPromises = getArrayOfPromises();
Promise.all(arrayOfPromises).then(array => doStuff(array));

我需要更改 getArrayOfPromises() 以返回有关每个承诺的一些信息 - 为简单起见,假设它是每个承诺的简单真/假标志。我的第一个直觉是重构这个函数以返回一个对象数组,例如:

const getArrayOfObjects = () => {
    ...
    return [
             { promise: promise1, flag: flag1 },
             { promise: promise2, flag: flag2 },
             ...
             { promise: promisen, flag: flagn }
           ];
}

但是,上述内容不适用于Promise.all,因为它只能直接用于可迭代的 Promise 对象,而没有中间的包装对象。

为每个 Promise 提供此类元数据并在解决所有 Promise 后使用它的最简单方法是什么?

【问题讨论】:

  • 最简单的方法是放在一个单独的数组中,使用doStuff里面的迭代索引
  • @ChrisG 不确定如何返回单独的数组 - 您可以发布示例代码作为答案吗? (也有点担心它不会非常节省内存,但可能会被误解。)
  • 1. return { arrayOfPromises: [...], arrayOfFlags: [...] }; 2.const { arrayOfPromises, arrayOfFlags } = getArrayOfObjects(); 3.doStuff(array, arrayOfFlags)
  • 有关承诺的信息”究竟是什么,以及将在何处/如何使用它?
  • 这是我的建议:jsfiddle.net/uf49rc8x(也应该比一堆新的 Promise 使用更少的内存)

标签: javascript arrays object promise metadata


【解决方案1】:

如果您想在 promise 被解析后使用此元数据,并且您无法控制由 getArrayOfPromises() 返回的 promise 解析的值,那么您可以简单地调用 then() on数组中的每个单独的承诺,并使其返回与您的元数据相结合的原始值。尽管确保将原始承诺替换为 .then() 返回的承诺。 Array.prototype.map() 让这一切变得简单:

arrayOfPromises = arrayOfPromises.map(promise => promise.then(value => ({
  value,
  flag: true
})));

例子:

let arrayOfPromises = getArrayOfPromises();
arrayOfPromises = arrayOfPromises.map(promise => promise.then(value => ({
  value,
  flag: true
})));

Promise.all(arrayOfPromises).then(array => doStuff(array));

function getArrayOfPromises() {
  return [sleep(1000), sleep(1500), sleep(2000)];
}

function doStuff(array) {
  console.log(array);
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(() => resolve('resolved after ' + ms), ms));
}

如果您确实可以控制getArrayOfPromises() 返回的内容,那么只需将元数据作为正在解析的值的一部分返回。

【讨论】:

  • 完美!你猜对了,我无法控制承诺/结果本身。现在已经应用了映射方法,并且效果很好。
【解决方案2】:

为每个 Promise 提供此类元数据并在解决所有 Promise 后使用它的最简单方法是什么?

只需将数据放入每个结果值中。它不是关于 Promise 的元数据,而是关于值 (?),在所有 Promise 都解决之前,您不需要使用它,因此结果是完美的地方。标志只是成为Promise.all(…) 解析为的array 的内容。

【讨论】:

  • 不幸的是,我无法访问结果值本身,因为承诺来自第三方库的函数调用。
  • @SteveChambers 没关系,把它们包在你自己的function(meta) { return thirdParty(meta).then(value => ({value, meta})); }
  • 谢谢,是的,这就是我现在正在做的事情(来自 Ivar 的回答)——关键是正在创建一套全新的 Promise,而我没有从你的原始回答中收集到。
猜你喜欢
  • 1970-01-01
  • 2017-05-17
  • 2016-11-25
  • 2020-04-24
  • 2022-08-20
  • 1970-01-01
  • 2018-05-05
  • 2017-06-22
  • 1970-01-01
相关资源
最近更新 更多