如何在Array.filter中传入异步回调?写法不生效原因及实现方案
问题原因
Array.filter本身是同步执行方法,不会等待回调内的异步操作完成,会直接读取回调的返回值做布尔判断。而async修饰的回调函数永远返回Promise实例,所有非空对象在JS布尔判断中都为true,最终会导致所有数组元素都被判定为符合条件,完全达不到筛选效果。- 你贴的代码本身还存在基础语法问题:
filter调用末尾多写了一个闭合括号,且Array是JS内置的数组构造函数,不是你要筛选的实际停车区域数组变量,直接调用会直接报错。
可行实现方案
异步场景下无法直接使用同步的filter完成筛选,需要先拿到所有异步校验的结果,再执行过滤逻辑,以下是两种常用实现:
方案1:并行校验(执行速度快)
用Promise.all搭配map并行发起所有校验请求,等所有请求返回后统一筛选,适合数组长度不大、没有接口并发限制的场景:
// 把zoneList替换成你实际要筛选的原始停车区域数组 async function getValidZones(zoneList) { // 并行执行所有区域的存在性校验 const checkResultList = await Promise.all( zoneList.map(async (zone) => { const existZone = await getOneParkingZone({ id: zone.id }) return { zoneData: zone, isExist: Boolean(existZone) } }) ) // 筛选出存在的区域并返回 return checkResultList.filter(item => item.isExist).map(item => item.zoneData) } // 调用时需要用await或者.then()获取结果 const result = await getValidZones(/* 传入你的原始区域数组 */)
方案2:顺序校验(请求压力小)
用for...of循环逐个发起校验请求,校验通过就直接加入结果数组,适合数组长度大、需要控制接口请求频率的场景:
async function getValidZonesSequential(zoneList) { const validResult = [] for (const zone of zoneList) { const existZone = await getOneParkingZone({ id: zone.id }) if (existZone) { validResult.push(zone) } } return validResult } // 调用示例 const result = await getValidZonesSequential(/* 传入你的原始区域数组 */)
注意:以上两个方法都是异步函数,返回值为Promise,必须使用
await或者.then()回调才能拿到最终筛选结果,不能同步直接取值。
内容的提问来源于stack exchange,提问作者Rishabh Singh
相关产品推荐
相关产品推荐

