Захват, когда последнее обещание разрешается в рекурсивном обещании - PullRequest
0 голосов
/ 01 февраля 2019

Я вызываю функцию, которая, по сути, возвращает обещание, которое разрешается либо списком, либо ничем.Затем я вызываю ту же функцию для каждого элемента в списке.В конце концов, все решится ни с чем.Я хотел бы запустить некоторый код только тогда, когда все решится, но не могу понять, как это сделать.

Чтобы упростить мою проблему, я создал этот пример.У меня есть контроль только над рекурсивной функцией.Сохранение всех обещаний в массив и передача их в 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 голосов
/ 01 февраля 2019

Если ожидаемый результат - только свойства timeCreated и timeResolved в одном объекте, вы можете объявить массив как переменную, .push() значения в массиве return Promise.all() с .map() вместо .forEach() и зарегистрируйте результат в цепочке .then().

Шаблон можно заменить на использование .reduce(), async/await с петлей for..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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...