使用async/await配合Array.some函数无法遍历数组全部元素如何解决?
异步数组some遍历仅执行第一个元素问题解决方案
问题原因
Array.prototype.some 是同步执行的遍历方法,你传入的async函数并不会返回布尔值,而是返回一个Promise实例。在JS中所有非空的Promise都属于truthy(真值),因此some方法判断第一个元素的返回值为真后,就直接终止遍历返回结果,因此只会触发第一个元素的console.log输出。
解决方法
方法1:串行执行(推荐,匹配原生some的短路特性,节省性能)
手动实现异步版的some逻辑,按顺序执行异步校验,只要匹配到符合条件的项就直接终止,不需要遍历完整个数组:
const account = 'foo' const exists = async (log: Log) => { console.log(log) return (await library.dosome(log.doanother)).account === account } let hasMatch = false for (const log of logs) { if (await exists(log)) { hasMatch = true break // 短路终止,和原生some行为完全一致 } } // 最终校验结果存储在hasMatch变量中
方法2:并行执行(适合数组长度短、允许同时发起所有异步请求的场景)
先批量发起所有异步校验请求,等全部返回后再判断是否存在符合条件的项:
const account = 'foo' const exists = async (log: Log) => { console.log(log) return (await library.dosome(log.doanother)).account === account } // 一次性执行所有异步请求 const results = await Promise.all(logs.map(exists)) const hasMatch = results.some(Boolean)
注意该方案没有短路逻辑,即使前几个已经匹配到符合条件的项,仍然会等所有请求执行完成才会返回最终结果。
额外提示:原代码存在潜在拼写错误:
(await library.dosome(log.doanother)).accout里的accout大概率是account的笔误,建议修正避免校验逻辑不符合预期。
内容的提问来源于stack exchange,提问作者user76333
相关产品推荐
相关产品推荐

