如何用JavaScript/Promises/Axios循环获取未知页数的分页数据?
解决未知分页数据的循环请求问题
原代码的核心问题
fetchData函数未返回Promise,导致await fetchData()没等待Axios请求完成就继续执行循环,page_number被提前自增,isWorking的修改因异步回调时机问题,无法同步影响循环判断。- 依赖全局变量
isWorking控制循环,异步操作下变量状态更新和循环判断时序不一致,逻辑失效。
最佳实现方案
用async/await链式调用替代.then()回调,直接在循环内判断请求结果,无需全局状态变量,保证每次请求完成后再决定是否继续下一页。
修正后的代码
const getHostname = (url) => { return new URL(url).hostname; }; const postedUrl = "https://example.com/"; const parsedUrl = getHostname(postedUrl); let page_number = 110; const productList = []; let total_products = 0; // 封装请求逻辑,返回Promise,明确是否还有数据 async function fetchPage(page) { try { const response = await axios.get(postedUrl, { params: { page } }); // 有数据则存入数组,更新总数量 if (response.data.length > 0) { productList.push(...response.data); total_products += response.data.length; return true; // 表示还有数据,继续请求 } return false; // 无数据,终止循环 } catch (err) { console.error(`请求第${page}页失败:`, err); // 可选:请求失败时的处理,比如重试一次或直接终止 return false; } } async function startFetching() { let hasMoreData = true; while (hasMoreData) { hasMoreData = await fetchPage(page_number); // 只有当有数据时才递增页码 if (hasMoreData) { page_number++; } } console.log("所有数据请求完成"); console.log("总产品数:", total_products); console.log("产品列表:", productList); } startFetching();
关键优化点
- 移除全局状态依赖:通过
fetchPage的返回值直接判断是否继续请求,避免异步状态不同步问题。 - 严格等待请求完成:确保每次请求结束后再处理结果、判断循环条件,页码仅在有数据时递增。
- 明确的错误处理:在
fetchPage内捕获请求错误,避免单个页面请求失败导致整个流程崩溃。 - 高效数据存储:用
push(...response.data)直接将当前页数据合并到全局数组,避免多次循环push单个元素。
额外建议
- 如果API有请求频率限制,可在循环中加入延迟,比如
await new Promise(resolve => setTimeout(resolve, 1000)),避免触发限流。 - 可添加最大重试次数,比如请求失败时重试2次再终止,提升鲁棒性。
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

