考虑以下简单的代码:
await Promise.all(arrayOfObjects.map(async (obj) => {
return await someAsyncFunctionOnObj(obj);
}));
我的问题是, arrayOfObjects 和 someAsyncFunctionOnObj ,在执行时占用太多内存,因为循环不等待执行完成,而是调用someAsyncFunctionOnObj (obj),在每一个上,等待全部解决,按顺序没有必要,这会导致OOM崩溃。 我尝试使用递归异步函数,这确实解决了订单问题,但仍导致OOM崩溃。
我想要实现的流程是一个同步循环,意思是
await someAsyncFunctionOnObj(obj1); // wait for it to finish
await someAsyncFunctionOnObj(obj2); // wait for it to finish
...
有关如何正确实施它的任何建议?
答案 0 :(得分:2)
async function queueAsyncFns(fns) {
const values = [];
await fns.reduce((previous, current, index, array) => {
const thenable = index === 1 ? previous() : previous;
return thenable.then(value => {
values.push(value);
return index === array.length - 1 ? current().then(value => values.push(value)) : current();
});
});
return values;
}
示例强>
const anArray = [1, 2, 3];
const doSomething = async (id) => await fetch(`https://jsonplaceholder.typicode.com/users/${id}`).then(res => res.json());
queueAsyncFns(anArray.map((val) => () => doSomething(val))).then((val) => console.log(val));
上述功能可以解决您的问题。以下是它的作用的简要概述:
queueAsyncFns
接受一组函数,这些函数返回调用异步函数的结果。通过调用每个函数并将Promise返回到reducer的下一次调用来减少此数组。每次迭代时,异步调用的值都会累积到一个名为values
的数组中,该数组在迭代完所有项后返回。
通过在运行示例时查看瀑布图,可以直观地确定函数的准确行为。您可以看到每个网络呼叫仅在上一个网络呼叫完成后才会进行。
答案 1 :(得分:1)
如果你想在做同样的事情之前等待someAsyncFunctionOnObj(obj1)完成但是使用下一个对象(obj2,obj3,...),我认为你必须链接你的承诺:
var promises = arrayOfObjects.map(obj => someAsyncFunctionOnObj(obj));
await promises.reduce((m, o) => m.then(() => o), Promise.resolve());
答案 2 :(得分:0)
(async function() {
async function executeSequentially() {
const tasks = [1,2]
const total = []
for (const fn of tasks) {
const res = await fetch(endpoint);
const res2 = await res.json();
console.log(res2[0]);
total.push(...res2);
}
return total;
}
const res = await executeSequentially();
console.log(res);
})();