为什么Array.filter搭配async函数总是返回全部元素?如何解决?
异步数组过滤失效问题解决
根本原因
Array.prototype.filter 是同步执行的原生方法,判断逻辑为:将谓词函数的返回值转为布尔值,为真则保留对应项。
而 async 函数的返回值永远是 Promise 对象,所有对象在布尔类型转换时都会被判定为 true,因此不管你在async函数内部返回什么,filter的判断结果全为真,最终返回全部数组元素。
实现方案
需要分两步实现异步过滤:
- 先并行执行所有异步谓词逻辑,拿到每一项对应的布尔过滤结果数组
- 用同步filter方法,结合结果数组过滤原数组
通用异步过滤函数实现
async function asyncFilter(arr, asyncPredicate) { // 并行执行所有异步判断,获取每一项的过滤结果 const filterResults = await Promise.all(arr.map(asyncPredicate)) // 结合结果过滤原数组 return arr.filter((item, index) => filterResults[index]) }
使用示例
// 测试调用 (async () => { // 可替换为你自己的异步判断逻辑,比如接口请求、文件读取等 const filterdArr = await asyncFilter([1,2,3], async (num) => { // 模拟异步操作 await new Promise(resolve => setTimeout(resolve, 10)) return num > 1 }) console.log(filterdArr) // 输出 [2, 3] })()
注意事项
如果数组长度极大,或者异步谓词是请求类操作,担心并行触发过多请求导致性能/限流问题,可以将并行执行的Promise.all改为串行遍历执行即可。
内容的提问来源于stack exchange,提问作者Yarh
相关产品推荐
相关产品推荐

