循环中Fetch请求无响应时如何持续获取网页并避免流程中断?
解决循环中批量请求因网络问题中断的方案
核心思路
- 给每个请求添加重试机制:短暂网络波动时自动重试,而非直接中断流程
- 隔离单个请求的异常:即使某条请求最终失败,也不影响后续请求执行
- 处理HTTP错误状态码:
fetch仅在网络故障时抛出异常,4xx/5xx这类状态码需要手动判断
封装带重试的请求函数
先写一个可复用的重试请求函数,支持自定义重试次数和间隔:
async function fetchWithRetry(url, maxRetries = 3, baseDelay = 1000) { let attempt = 0; while (attempt < maxRetries) { try { const res = await fetch(url); // 手动校验HTTP状态码,非2xx视为请求失败 if (!res.ok) { throw new Error(`HTTP错误!状态码: ${res.status}`); } return res; } catch (err) { attempt++; if (attempt >= maxRetries) { // 达到最大重试次数,抛出最终错误 throw new Error(`经过${maxRetries}次尝试后失败: ${err.message}`); } // 重试间隔指数增长,避免频繁请求给服务器施压 await new Promise(resolve => setTimeout(resolve, baseDelay * attempt)); } } }
修改批量请求循环
把原循环改造为带异常捕获的逻辑,确保单个请求失败不中断整体流程:
async function processNodes(nodeList) { for (const node of nodeList) { const url = node.getAttribute('href'); if (!url) continue; // 跳过无有效链接的节点 try { const res = await fetchWithRetry(url); const html = await res.text(); const scraper = new DOMParser(); const doc = scraper.parseFromString(html, 'text/html'); // 修正原代码变量名错误 alert(`成功解析链接: ${url}`); // 这里添加处理解析后文档的业务逻辑 } catch (err) { // 单个请求失败,记录错误后继续处理下一个 console.error(`处理链接失败 ${url}:`, err.message); continue; } } } // 调用示例 // processNodes(你的节点列表);
关键细节说明
- 重试策略:默认3次重试,间隔1s、2s、3s指数增长,可根据需求调整
maxRetries和baseDelay - 状态码校验:必须判断
res.ok,否则404、500这类服务器错误不会触发异常捕获 - 变量修正:原代码中存在
response、text等未定义变量,示例中已修正 - 无效链接过滤:提前跳过无href的节点,避免无效请求浪费资源
内容的提问来源于stack exchange,提问作者dvtpetrosyan
相关产品推荐
相关产品推荐

