等待异步功能完成内部地图

时间:2017-10-18 11:03:54

标签: javascript typescript asynchronous

考虑以下简单的代码:

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
...

有关如何正确实施它的任何建议?

3 个答案:

答案 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的数组中,该数组在迭代完所有项后返回。

通过在运行示例时查看瀑布图,可以直观地确定函数的准确行为。您可以看到每个网络呼叫仅在上一个网络呼叫完成后才会进行。

queueAsyncFns waterfall graph

答案 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);
})();