使用异步/等待的数组reduce函数

5
“我正在尝试根据异步操作从数组对象中跳过一个对象。我尝试了以下方法,但出现了类型错误。
尝试的方法1”
newObjectArray = await Promise.all(objectAray.reduce(async (result, el) => {
  const asyncResult = await someAsyncTask(el);
  if (asyncResult) {
      result.push(newSavedFile);
  }
  return result;
}, []));

尝试了方法2

newObjectArray = await Promise.all(objectAray.reduce(async (prevPromise, el) => {
  const collection = await prevPromise;
  const asyncResult = await someAsyncTask(el);
  if (asyncResult) {
      prevPromise.push(newSavedFile);
  }

  collection.push(newSavedFile);
  return collection;
}, Promise.resolve([])));

错误
'TypeError: #<Promise> is not iterable',
'    at Function.all (<anonymous>)',

请问您能解释一下期望的输出是什么吗? - gr4viton
1个回答

15
在您的第一次尝试中,result 是一个 promise。所有async函数在被调用时会返回一个promise,所以在将其推入数组之前,您需要 await result,然后就不需要Promise.all了。
 newObjectArray = await objectAray.reduce(async (result, el) => {
  const asyncResult = await someAsyncTask(el);
  if (asyncResult) {
    (await result).push(newSavedFile);
  }
  return result;
}, []);

但我猜只是过滤后速度会更快:

 newObjectArray = (await Promise.all(objArray.map(someAsyncTask))).filter(el => el);

1
过滤器不会导致对数组进行双重迭代的开销吗? - Ankit Balyan
2
@ankit,是的,这可能会花费你几个纳秒的时间,而在执行一个someAsyncTask之后再执行另一个将需要更多的时间。只需在此之前和之后放置一个Date.now(),并查看两者的性能... - Jonas Wilms
谢谢你的答复。当我将其缩小至对象时,无法使用Promise.all()。所以我非常喜欢你的回答,它帮助了我的目的 :) 谢谢! - To Kra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接