前端基于fetch API的请求超时与重试函数封装

在前端开发中,处理请求超时和重试是一个常见的需求。我们可以通过封装一个通用的函数来实现这个功能。以下是一个基于 fetch
API 的示例代码,它支持设置超时时间和重试次数:
/**
* 封装一个支持超时和重试的请求函数
* @param {string} url - 请求的URL
* @param {Object} options - 请求的配置项,同fetch的options
* @param {number} timeout - 超时时间,单位毫秒
* @param {number} retries - 重试次数
* @returns {Promise<Response>} - 返回fetch的响应
*/
async function fetchWithTimeoutAndRetry(url, options = {}, timeout = 5000, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
// 创建一个超时控制器
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
// 发起请求
const response = await fetch(url, {
...options,
signal: controller.signal
});
// 清除超时定时器
clearTimeout(timeoutId);
// 如果请求成功,返回响应
if (response.ok) {
return response;
} else {
throw new Error(`Request failed with status ${response.status}`);
}
} catch (error) {
// 如果是最后一次重试,抛出错误
if (i === retries - 1) {
throw new Error(`Request failed after ${retries} retries: ${error.message}`);
}
console.warn(`Attempt ${i + 1} failed: ${error.message}. Retrying...`);
}
}
}
// 使用示例
fetchWithTimeoutAndRetry('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}, 5000, 3)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
代码解析:
-
超时控制:我们使用
AbortController
来控制请求的超时。如果在指定的timeout
时间内请求没有完成,controller.abort()
会被调用,从而中断请求。 -
重试机制:如果请求失败(包括超时或网络错误),代码会捕获错误并进行重试。重试次数由
retries
参数控制。 -
错误处理:如果所有重试都失败,最终会抛出一个错误,提示请求失败。
-
使用示例:展示了如何使用这个封装函数来发起一个带有超时和重试机制的请求。
注意事项:
- 这个实现是基于
fetch
API 的,如果你使用的是其他请求库(如axios
),可能需要调整实现方式。 - 超时时间
timeout
和重试次数retries
可以根据实际需求进行调整。 - 在实际项目中,你可能还需要处理更多的边界情况,比如请求取消、网络状态检测等。
这个封装函数可以帮助你在前端应用中更好地处理网络请求的不稳定性,提升用户体验。