简体   繁体   English

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

[英]Capture when the last promise resolves in a recursive promise

I am calling a function which essentially returns a promise that resolves with either a list or nothing. 我正在调用一个函数,该函数本质上返回一个用列表或什么都不解决的promise。 I then call the same function for each item in the list. 然后,我为列表中的每个项目调用相同的函数。 Eventually, all will resolve with nothing. 最终,所有人都将一事无成。 I would like to run some code only when all resolve, but cannot figure out how to do that. 我只想在所有问题解决后再运行一些代码,但无法弄清楚该怎么做。

To simplify my problem I created this example. 为了简化我的问题,我创建了这个示例。 I have control only over the recursive function. 我只能控制递归函数。 Saving all the promises to an array and passing it to Promises.all() in sample below: 将所有的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)); 

doesn't work because Promise.all() will get called before the array is fully populated. 不起作用,因为Promise.all()将在数组完全填充之前被调用。

If the expected result is only the timeCreated and timeResolved properties in a single object you can declare an array as a variable, .push() the values to the array return Promise.all() from .map() instead of .forEach() and log the result at chained .then() . 如果预期的结果是只有 timeCreatedtimeResolved在单个对象的属性可以声明数组作为一个变量, .push()中的值到所述阵列return Promise.all().map()代替.forEach()并将结果记录在链接的.then()

The pattern can be substituted for use of .reduce() , async/await with for..of loop or other patterns. 该模式可以用for..of .reduce()async/awaitfor..of循环或其他模式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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM