2024/03/11 请求重试的多种方案
请求重试的多种方案
背景: 在跨境业务中,可能第三方的服务器分布在世界的各个角落,所以请求三方接口的时候,难免会遇到一些网络问题,这时候需要加入重试机制了,这期就给大家分享几个接口重试的写法。
接口请求重试的8种方法,你用哪种?
1. 使用async/await来处理异步操作。
async function fetchWithRetry(url, maxRetries, retryDelay) { let retries = 0; while (retries < maxRetries) { try { const response = await fetch(url); if (response.ok) { return response.json(); // 返回 JSON 响应 } else { throw new Error('Network response was not ok.'); } } catch (error) { console.error(`Request failed, retrying (${retries + 1}/${maxRetries})`); await new Promise(resolve => setTimeout(resolve, retryDelay)); // 等待一段时间后重试 retries++; } } throw new Error('Request failed after maximum retries.'); } // 使用示例 const url = 'https://api.example.com/data'; const maxRetries = 3; const retryDelay = 1000; // 1秒 fetchWithRetry(url, maxRetries, retryDelay) .then(data => { console.log('Data:', data); }) .catch(error => { console.error('Failed to fetch data:', error); });
2. 使用 Axios 拦截器:如果您在项目中使用 Axios 发起网络请求,可以使用 Axios 的拦截器来处理请求重试。拦截器允许您在请求发送或响应返回时执行自定义逻辑,这样可以很方便地实现请求重试。
import axios from 'axios'; const instance = axios.create(); instance.interceptors.response.use( response => response, error => { const { config, response } = error; if (response && response.status === 500) { // 如果请求失败且响应状态码为 500,进行重试 return axios(config); } return Promise.reject(error); } ); // 使用示例 instance.get('https://api.example.com/data') .then(response => { console.log('Data:', response.data); }) .catch(error => { console.error('Failed to fetch data:', error); });
3. 使用超时设置:在一些网络请求库中,您可以设置请求的超时时间。如果请求在超时时间内没有得到响应,您可以通过捕获错误并重新发起请求来实现请求重试。
const axios = require('axios');
function fetchWithTimeoutRetry(url, maxRetries, timeout) {
let retries = 0;
const instance = axios.create({ timeout });
function doRequest() {
return instance.get(url)
.catch(error => {
if (retries < maxRetries) {
console.error(`Request failed, retrying (${retries + 1}/${maxRetries})`);
retries++;
return doRequest(); // 重试请求
} else {
return Promise.reject(error);
}
});
}
return doRequest();
}
// 使用示例
const url = 'https://api.example.com/data';
const maxRetries = 3;
const timeout = 5000; // 5秒
fetchWithTimeoutRetry(url, maxRetries, timeout)
.then(response => {
console.log('Data:', response.data);
})
.catch(error => {
console.error('Failed to fetch data:', error);
});
4. **使用 Promise.race() 和 setTimeout()**:您可以使用Promise.race()来比较原始请求和超时触发的请求哪个更快返回。如果原始请求超时,您可以重新发起请求。
function fetchWithTimeoutRetry(url, maxRetries, timeout) { let retries = 0; function doRequest() { return Promise.race([ fetch(url), new Promise((resolve, reject) => { setTimeout(() => reject(new Error('Request timeout')), timeout); }) ]).then(response => { if (response.ok) { return response.json(); } else { throw new Error('Network response was not ok.'); } }).catch(error => { if (retries < maxRetries) { console.error(`Request failed, retrying (${retries + 1}/${maxRetries})`); retries++; return doRequest(); // 重试请求 } else { throw error; } }); } return doRequest(); } // 使用示例 const url = 'https://api.example.com/data'; const maxRetries = 3; const timeout = 5000; // 5秒 fetchWithTimeoutRetry(url, maxRetries, timeout) .then(data => { console.log('Data:', data); }) .catch(error => { console.error('Failed to fetch data:', error); });
5. 使用类库或工具:除了手动处理重试逻辑外,还有一些专门用于处理网络请求重试的类库和工具,例如axios-retry。这些类库和工具通常提供了一些方便的配置选项,使得实现请求重试变得更加简单。
const axios = require('axios');
const axiosRetry = require('axios-retry');
axiosRetry(axios, { retries: 3, retryDelay: axiosRetry.exponentialDelay });
// 使用示例
axios.get('https://api.example.com/data')
.then(response => {
console.log('Data:', response.data);
})
.catch(error => {
console.error('Failed to fetch data:', error);
});

浙公网安备 33010602011771号