const result = [1, 2, 3, 4, 5].filter(async (n) => n <= 3)
如果你 console.log(result) 你会得到 [1, 2, 3, 4, 5]。为什么不是[1,2,3]?
如果从函数中删除 async,你会得到 [1, 2, 3]。
我只是想知道为什么会这样。
filter
使用原始数组中的所有值创建一个新数组,其中您传递的函数返回一个 true 值。
async
函数返回 Promises。承诺是对象。对象是true值。
如果您想使用异步函数执行此操作,则需要等到解决了承诺之后才能测试真实性。
!async function() {
const data = [1, 2, 3, 4, 5];
const promises = data.map(async(n) => ({
value: n,
include: n <= 3
}));
const data_with_includes = await Promise.all(promises);
const filtered_data_with_includes = data_with_includes.filter(v => v.include);
const filtered_data = filtered_data_with_includes.map(data => data.value);
console.log(filtered_data);
}();
或者,采用不解释每个步骤的格式:
!async function() {
const result = (await Promise.all([1, 2, 3, 4, 5].map(async(n) => ({
value: n,
include: n <= 3
})))).filter(v => v.include).map(data => data.value);
console.log(result);
}();
您还可以避免使用函数方法来支持在
for
循环中进行突变
!async function() {
const test = async(n) => n <= 3;
const data = [1, 2, 3, 4, 5];
const result = [];
for (let i = 0; i < data.length; i++) {
const value = data[i];
if (await test(value)) result.push(value);
}
console.log(result);
}();
我遇到了同样的问题,所以你可以实现异步过滤器 fn:
async function asyncFilter<T>(arr: T[], cb: (el: T) => Promise<boolean>): Promise<T[]> {
const filtered: T[] = [];
for (const element of arr) {
const needAdd = await cb(element);
if (needAdd) {
filtered.push(element);
}
}
return filtered;
}