首页 > 解决方案 > 在 Array.find() 中使用异步函数

问题描述

看来我无法使用异步函数作为 Array.find() 的第一个参数。我不明白为什么这段代码不起作用,幕后发生了什么?


function returnsPromise() {
  return new Promise(resolve => resolve("done"));
}

async function findThing() {
  const promiseReturn = await returnsPromise();
  return promiseReturn;
}

async function run() {
  const arr = [1, 2];
  const found = await arr.find(async thing => {
    const ret = await findThing();
    console.log("runs once", thing);
    return false;
  });
  console.log("doesn't wait");
}

run();

https://codesandbox.io/s/zk8ny3ol03

标签: javascript

解决方案


简单地说,find不期望返回一个promise,因为它不是用于异步的东西。它循环遍历数组,直到其中一个元素导致返回真值。一个对象,包括一个 Promise 对象,是真实的,因此查找停止在第一个元素上。

如果你想要一个异步的 find 等价物,你需要自己写。您需要考虑的一个问题是您是要并行运行事物,还是要顺序运行它们,在继续下一个索引之前阻塞。

例如,这是一个并行运行它们的版本,然后一旦所有承诺都解决了,它就会找到第一个产生真值的。

async function findAsync(arr, asyncCallback) {
  const promises = arr.map(asyncCallback);
  const results = await Promise.all(promises);
  const index = results.findIndex(result => result);
  return arr[index];
}

//... to be used like:

findAsync(arr, async (thing) => {
  const ret = await findThing();
  return false;
})

推荐阅读