JS高并发请求拉取数据后读取Array数组total属性报undefined错误如何解决
问题根因分析
- 报错的核心原因是你在判断total是否为undefined之前,就已经尝试从undefined的数组项上读取total属性,后续的判断逻辑根本没有执行的机会,所以你的规避方案不生效。
tradeCoinHistoryArray[i]本身为undefined时,读取.total会直接抛出类型错误,和total本身是否为undefined无关。 - 高频请求触发接口异常返回:5秒500次的请求频率大概率会触发站点限流,接口返回非预期结构,比如
importedJSON.data不是数组、或者数组长度小于TRADE_LAST_TRADE_COUNT,此时你计算出的循环起始下标为负数,访问负下标的数组项自然得到undefined。 - 现有判断逻辑的错误:你在遇到异常时用了
return,会直接终止整个请求回调的执行,如果你只是想跳过当前异常项,应该用continue。
修复方案
1. 增加接口返回数据前置校验
在遍历前先校验返回数据的合法性,避免异常结构进入遍历逻辑:
request(TRADE_HISTORY_URL + coin, function (error, response, body) { if (!error && response.statusCode == 200) { var importedJSON = JSON.parse(body); // 新增前置校验:判断data是否为数组、长度是否满足遍历要求 if (!Array.isArray(importedJSON.data) || importedJSON.data.length < TRADE_LAST_TRADE_COUNT) { // 可自行增加日志记录异常返回,方便后续排查 return } tradeCoinHistoryArray = importedJSON.data; // 后续遍历逻辑 } })
2. 调整遍历内的取值判断顺序
先判断数组项是否存在,再读取属性:
for (var i = tradeCoinHistoryArray.length - TRADE_LAST_TRADE_COUNT; i < tradeCoinHistoryArray.length; i++) { const currentItem = tradeCoinHistoryArray[i] // 先判断当前项是否存在,再判断total是否合法 if (!currentItem || currentItem.total === undefined) { // 仅跳过当前异常项用continue,不要用return终止整个循环 continue } const total = currentItem.total // 后续正常业务逻辑 }
3. 补充请求限流策略
高频请求不仅容易触发接口限流返回异常,也会给站点带来不必要的压力,建议引入请求队列控制并发数,或者给请求加固定间隔的延迟,把请求频率控制在站点允许的范围内。
内容的提问来源于stack exchange,提问作者İsa C.
相关产品推荐
相关产品推荐

