【发布时间】:2019-02-01 01:32:01
【问题描述】:
我正在调用一个函数,该函数本质上返回一个用列表或什么都解决的承诺。然后我为列表中的每个项目调用相同的函数。最终,一切都将一无所有。我只想在所有代码都解决后才运行一些代码,但不知道该怎么做。
为了简化我的问题,我创建了这个示例。我只能控制递归函数。将所有的 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() 将在数组完全填充之前被调用。
【问题讨论】:
-
recursive2(smallerArr)在.forEach()中的预期结果是什么?在哪个递归调用中arr不是数组? -
承诺的全部意义不在于拥抱 JS 的异步特性吗?我的意思是你可以返回 Promises(一旦解决就会变成值),这允许你的程序在这些 Promise 等待它们的返回值时评估 unblocked。控制台记录这些值,它捕获了 console.log 点的值状态,实际上并不能帮助您了解承诺正在解决什么,因为它们不会等待任何值,就像运行时等待任何底层不完整异步操作。有用的帖子:blog.domenic.me/youre-missing-the-point-of-promises
-
vals.then()链接到Promise.all()的预期结果是什么? -
@jaredgorski - 所有的优点。但是,有些用例会驱动多个同时进行的异步操作,这些操作最终会形成最终用户需要的信息架构。一个例子可能是使用微服务或 FAAS 类型系统。在这种情况下,OP 有一个很好的问题。
-
顺便说一句,这推动了 JavaScript 语言中 async/await 的采用。
标签: javascript promise