如何在承诺解决时处理承诺?

How to handle promises as they resolve?

目前,此代码打印出一个零,因为数组中的第一个承诺会立即解析。

const promises = [];
const promiser = (number) => new Promise((resolve, reject) => window.setTimeout(() => resolve(number), number * 100));
for (let index = 0; index < 10; index++) {
  const promise = promiser(index);
  promises.push(promise);
}

Promise.race(promises).then(r => console.debug(r));

我希望做到这一点,以便一旦最快的承诺解决,它就会从 promises 数组中删除,并使用剩余的承诺进行新的 Promise.race 调用,重复直到没有留下了承诺。

由于 Promise.race return 是 promise 的结果,而不是已解决的 promise 本身,所以我无法确定哪个 promise 已解决,我也不知道要解决哪个从数组中删除。有办法知道吗?我想我可以 return 一个具有某种关联键和结果的复杂对象,但这看起来很奇怪。我希望 Promise.race 回调的第二个参数是承诺的索引,但事实并非如此,这也没有意义,因为 then 只是另一个的 then promise,所以它怎么知道它应该 return 一些索引呢。你能想到更好的办法吗?

此外,我 运行 对第一个 race 的所有承诺,但这对后续的 race 应该不是问题,对吧?如果在随后的 race 调用之前同时解决了另一个承诺,它应该 return 它,没问题,对吗?如果同时解决了多个承诺,它只会 return 第一个(按数组顺序还是按解析顺序?)然后下一个 race 会 return 第二个,依此类推……对吗?

顺便说一句,虽然我可以遍历数组并删除具有 isResolved 的承诺,但这不是真实的。但是,即使是这样,对于 race.

调用之间解决多个承诺的情况,这也会完全中断

您可以return 承诺的标识符

const promises = [];
const promiser = (number, id) => new Promise((resolve, reject) => window.setTimeout(() => resolve({ number, id }), number * 100));
for (let index = 0; index < 10; index++) {
  const promise = promiser(index, "id_" + index);
  promises.push(promise);
}

Promise.race(promises).then(r => console.debug(r.id));

无论如何,如果您正在使用诸如 bluebird 之类的 promise 库,您可以找到一些实用程序来帮助您更好地构建代码(例如 Promise.reducePromise.any

I'm looking to make it so that once the quickest promise resolves, it is removed from the promises array and a new Promise.race call is made with the remaining promises, repeating until no promise is left.

如果你最终想要处理 all 承诺,为什么要使用 Promise.race?难道你不能简单地在每个 promise 都 resolve 之后就处理它,然后等到所有 promise 都处理完了吗?

const promises = [];
const promiser = (number) => new Promise((resolve, reject) => window.setTimeout(() => resolve(number), number * 100));

for (let index = 0; index < 10; index++) {
  const promise = promiser(index)
      .then(r => process(r)); // process every promise individually
  promises.push(promise);
}

Promise.all(promises) // wait for all promises to be processed
       .then(r => console.debug('all done!'));

或者 process 也是 异步的,你需要确保一次只处理一个承诺?