如何解决承诺?

时间:2016-08-07 09:08:45

标签: javascript node.js typescript promise es6-promise

目前,此代码打印出零,因为数组中的第一个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);
  promises.push(promise);
}

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

我希望这样做,以便一旦最快的承诺解决,它就会从promises数组中移除,并且对剩余的承诺进行新的Promise.race调用,重复直到没有承诺为止左

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

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

顺便说一下,我也可以走数组并删除isResolved的承诺,但这不是真的。但即使是这样,对于在race的调用之间解决多个承诺的情况,这也会完全破裂。

2 个答案:

答案 0 :(得分:5)

  

我希望这样做,以便一旦最快的承诺解决,它就会从promises数组中移除,并且对剩余的承诺进行新的Promise.race调用,重复直到没有承诺为止左

如果您最终想要处理所有承诺,为什么要使用Promise.race?难道你不能在结算后立即处理每一个承诺,然后等到所有承诺都被处理完毕?

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 也是是异步的,您需要确保一次只处理一个承诺吗?

答案 1 :(得分:1)

您可以将标识符返回到承诺

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.reducePromise.any