使用offset参数分页拉取接口数据时出现无限循环,该如何排查?
问题定位与修复
核心原因
你代码的死循环问题来自Array.concat()方法的错误使用:
- JavaScript中
concat不会修改调用它的原数组,只会返回拼接完成的新数组。你代码中array.concat(tempResponse);没有将返回值赋值回array变量,导致array的长度永远停留在首次请求返回的299条,offset每次都会被赋值为299,所有分页请求的offset参数固定不变,返回结果完全一致,无法跳出循环。
其他冗余问题
- 首次请求已经拉取了offset=0的第一页数据,进入while循环后会再次请求offset=0的相同接口,存在重复请求,浪费接口请求资源。
修复后的代码
async function fetchData (contractAddress, tokenID) { let offset = 0; let array = []; let tempResponse = []; do { const urlPage = `https://api.website.io/api/v1/events?asset_contract_address=${contractAddress}&token_id=${tokenID}&offset=${offset}&limit=299`; logger.log(urlPage); const pageRes = await internalFetch(urlPage, { headers: { 'Accept': 'application/json', 'X-Api-Key': API_KEY, }, method: 'get', timeout: 10000, }) tempResponse = pageRes.data.asset_events; // 拼接新数据到原数组,也可以用 array.push(...tempResponse) 直接修改原数组,性能更好 array = array.concat(tempResponse); offset = array.length; logger.log("length " + offset); } while (tempResponse.length !== 0) return array; }
修复说明
- 改用do...while循环统一分页逻辑,删除冗余的首次单独请求,避免重复拉取第一页数据
- 将
concat的返回值重新赋值给array,保证数组长度和offset可以正常累加 - 把
var替换为let避免变量提升带来的潜在问题,也可以根据需要改用const声明不变的配置项
内容的提问来源于stack exchange,提问作者kalculated
相关产品推荐
相关产品推荐

