如何找出 Promise.any 解决了哪个 Promise?

问题描述 投票:0回答:3

我正在使用

Promise.all
进行一些批量 IO,但最终我通过一次创建太多 IO 承诺而达到了打开文件的限制。因此,我制作了一个实用程序,它将最多以 50 个批次运行这些承诺。

一种解决方案是将任务分成 50 批,然后对每批执行

Promise.all
。但更明智的解决方案是使用
Promise.any
来循环承诺。问题是,
Promise.any
只返回结果,而不返回哪个promise。

如何找出已解决的问题,以便我可以在批次中用新的未解决的问题替换它?

javascript ecmascript-6 promise
3个回答
3
投票

没有本地方法可以找到已完成的

Promise

但我想到了一个解决方法。基本上,我为每个

Promise
分配了一个 id,然后解构
Promise
的返回值并注销 id 和结果

const Promise4 = fetch('https://pokeapi.co/api/v2/ability/?limit=1&offset=20').then(response => response.json()).then(result => ({
  id: 4,
  result
}));
const Promise1 = fetch('https://pokeapi.co/api/v2/ability/?limit=1&offset=12').then(response => response.json()).then(result => ({
  id: 1,
  result
}));
const Promise2 = fetch('https://pokeapi.co/api/v2/ability/?limit=1&offset=5').then(response => response.json()).then(result => ({
  id: 2,
  result
}));
const Promise3 = fetch('https://pokeapi.co/api/v2/ability/?limit=1&offset=23').then(response => response.json()).then(result => ({
  id: 3,
  result
}));


Promise.any([Promise1, Promise2, Promise3, Promise4]).then(({
  id,
  result
}) => console.log(`Promise${id} returned`, result.results[0].name));


0
投票

与a.mola的答案类似,但保持承诺索引跟踪更接近

Promise.any
调用,我们可以在输入数组上
map
添加标签并解构以检索它:

const promises = [
  new Promise(resolve => setTimeout(() => resolve("p0value"), 1000)),
  new Promise(resolve => setTimeout(() => resolve("p1value"), 500))
];

const promiseAnyIndexed = pp => Promise.any(pp.map((p,i)=>p.then(res=>[res,i])));

const [res, i] = await promiseAnyIndexed(promises);

console.log(res,i);    // p1value 1

0
投票

在这里留下我的 2 美分:我喜欢做的是覆盖返回值以包含承诺本身,以便它可以轻松匹配:

export function refPromise(promise) {
  // This function ensures a promise resolves/rejects with a reference to itself, so usage in methods
  // like 'Promise.race' or 'Promise.any' allows us to know which promise returned.
  const refPromise = promise
    .then((value) => {
      return { promise: refPromise, value };
    })
    .catch((reason) => {
      throw { promise: refPromise, reason };
    });
  return refPromise;
}

这是一个例子:

const p1 = refPromise(new Promise((r) => setTimeout(() => r("a"), 1000)));
const p2 = refPromise(new Promise((r) => setTimeout(() => r("b"), 500)));
try {
  const { promise, value } = await Promise.any([p1, p2]);
  if (promise === p1) {
    console.log("p1 resolved!", value);
  } else if (promise === p2) {
    console.log("p2 resolved!", value);
  }
} catch (e) {
  const { promise, reason } = e;
  // Can treat 'promise' the same way as above
}
© www.soinside.com 2019 - 2024. All rights reserved.