在最后一个承诺解析为递归承诺时捕获

时间:2019-02-01 01:32:02

标签: javascript promise

我正在调用一个函数,该函数本质上返回一个用列表或什么都不解决的promise。然后,我为列表中的每个项目调用相同的函数。最终,所有人都将一事无成。我只想在所有问题解决后才运行一些代码,但无法弄清楚该怎么做。

为简化我的问题,我创建了此示例。我只能控制递归函数。将所有的promise保存到一个数组中,并将其传递给以下示例中的Promises.all():

function randomLowerInt(int) {
  return parseInt(Math.random() * int);
}

function smallerArray(size) {
  const arr = [];
  const smallerSize = randomLowerInt(size);
  for (let i = 0; i < smallerSize; i++) {
    arr.push(i);
  }
  return arr;
}

function createPromise(arrLength) {
  const secnds = parseInt(Math.random() * 20) * 1000;
  const timeCreated = new Date().getTime();
  const p = new Promise(res => {
    setTimeout(() => {
      const timeResolved = new Date().getTime();
      res({
        timeCreated,
        timeResolved,
        arrLength
      });
    }, secnds);
  });
  return p;
}

function recursive(arr) {
  arr.forEach(() => {
    createPromise(arr.length).then(({
      timeCreated,
      timeResolved,
      arrLength
    }) => {
//      console.log({
//        timeCreated,
//        timeResolved
//      });
      const smallerArr = smallerArray(arrLength);
      recursive(smallerArr);
    });
  });
}
recursive([1, 2, 3, 4, 5]);

const promises = [];

function recursive2(arr) {
  arr.forEach(() => {
    const p = createPromise(arr.length).then(({
      timeCreated,
      timeResolved,
      arrLength
    }) => {
      const smallerArr = smallerArray(arrLength);
      recursive2(smallerArr);
      return ({
        timeCreated,
        timeResolved
      });
    });
    promises.push(p);
  });
}
recursive2([1, 2, 3, 4, 5]);
console.log('Waiting...');
Promise.all(promises).then(vals => console.log(vals));

不起作用,因为Promise.all()将在数组完全填充之前被调用。

1 个答案:

答案 0 :(得分:0)

如果预期结果仅为 一个对象中的timeCreatedtimeResolved属性,则可以将数组声明为变量,.push()的值应为从return而不是Promise.all()的数组.map() .forEach()开始,并将结果记录在链接的.then()处。

可以使用.reduce()async/awaitfor..of循环或其他模式来替换该模式。

let res = []
function recursive(arr) {
  return arr.map((promise) => {
    return createPromise(arr.length).then(({ timeCreated, timeResolved, arrLength }) => {
      console.log({ timeCreated, timeResolved });
      res.push({ timeCreated, timeResolved });
      const smallerArr = smallerArray(arrLength);
      return Promise.all(recursive(smallerArr));
    });
  });
}

Promise.all(recursive([1, 2, 3, 4, 5])).then(() => console.log(res));