似乎我无法使用异步函数作为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();
答案 0 :(得分:4)
简而言之,find
不会返回承诺,因为它不是用于异步事物的。它循环遍历数组,直到其中一个元素导致返回真实值。一个对象(包括一个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;
})
答案 1 :(得分:2)
这是一个按顺序运行的TypeScript版本:
async function findAsyncSequential<T>(
array: T[],
predicate: (t: T) => Promise<boolean>,
): Promise<T | undefined> {
for (const t of array) {
if (await predicate(t)) {
return t;
}
}
return undefined;
}
答案 2 :(得分:0)
它可能会帮助您注意Array.prototype.filter
是同步的,因此它不支持异步行为。我认为“ find”属性也是如此。您始终可以定义自己的异步属性:)希望能有所帮助!
答案 3 :(得分:0)
我的猜测是,您正在尝试执行以下操作,该操作在for循环中使用await,一旦找到所需内容,该操作就会中断
async function findThing(n) {
return Promise.resolve({id: n})
}
async function run(wanted) {
const arr = [1, 2, 3, 4, 5, 6];
let found
for (let n of arr) {
const item = await findThing(n)
if (item.id === wanted) {
found = item;
break
} else {
console.log('Not wanted:', JSON.stringify(item))
}
}
console.log("found:", found);
}
const wanted = 4;
run(wanted);
.as-console-wrapper {max-height:100%!important;}