UniApp的request请求自动重试机制实现
你好,UniApp世界的探险家们! 🌍
大家好!今天我们要一起探讨一个非常有趣且实用的话题:如何在UniApp中实现request
请求的自动重试机制。想象一下,你正在开发一个APP,用户在点击某个按钮时需要发送一个网络请求。但有时候,网络可能会“打个盹儿” 😴,导致请求失败。这时候,如果能自动再试一次,用户体验是不是会好很多呢?😏
那么,我们今天就来聊聊如何优雅地实现这个功能。准备好了吗?让我们开始吧!
什么是自动重试机制?
简单来说,自动重试机制就是在网络请求失败时,程序会自动再次发起请求,而不是直接告诉用户“出错了”。这样可以避免用户频繁手动刷新页面或重新操作,提升用户体验。
为什么要实现自动重试?
- 网络波动:移动网络不稳定是常见的问题,尤其是在切换Wi-Fi和4G/5G时,可能会导致请求失败。
- 服务器负载:当服务器负载过高时,可能会返回503(服务不可用)等错误,此时重试可以帮助用户顺利完成操作。
- 用户友好:自动重试可以让用户无感知地完成操作,减少他们的焦虑感。
UniApp中的request
方法
在UniApp中,uni.request
是用于发起HTTP请求的核心API。它的基本用法如下:
uni.request({
url: 'https://example.com/api/data',
method: 'GET',
success(res) {
console.log('请求成功:', res.data);
},
fail(err) {
console.error('请求失败:', err);
}
});
但是,当我们遇到网络问题时,fail
回调会被触发,这时候我们需要做些什么呢?🤔
实现自动重试的思路
要实现自动重试,我们需要考虑以下几个问题:
- 重试几次:不能无限次重试,否则可能会陷入死循环。通常我们会设置一个最大重试次数。
- 重试间隔:每次重试之间应该有一定的间隔时间,避免短时间内频繁请求服务器。
- 重试条件:并不是所有错误都需要重试,比如404(资源未找到)这种错误就没有必要重试。
- 用户提示:如果重试多次仍然失败,应该给用户一个友好的提示。
代码实现
我们可以封装一个自定义的request
函数,加入自动重试的逻辑。下面是一个简单的实现:
function requestWithRetry(options, retryCount = 3, delay = 1000) {
return new Promise((resolve, reject) => {
function makeRequest(attempt = 1) {
uni.request({
...options,
success(res) {
resolve(res); // 请求成功,直接返回结果
},
fail(err) {
if (attempt >= retryCount) {
// 达到最大重试次数,放弃重试
reject(err);
return;
}
console.warn(`第 ${attempt} 次请求失败,将在 ${delay}ms 后重试...`);
// 等待一段时间后重试
setTimeout(() => {
makeRequest(attempt + 1);
}, delay);
}
});
}
makeRequest(); // 第一次请求
});
}
参数说明
options
:uni.request
的配置项,包括url
、method
、data
等。retryCount
:最大重试次数,默认为3次。delay
:每次重试之间的间隔时间,默认为1秒(1000ms)。
使用示例
requestWithRetry({
url: 'https://example.com/api/data',
method: 'GET'
}).then(res => {
console.log('最终请求成功:', res.data);
}).catch(err => {
console.error('请求失败,已达到最大重试次数:', err);
});
进阶优化:根据错误码决定是否重试
并不是所有的错误都需要重试。例如,404错误表示资源不存在,重试也不会有帮助。因此,我们可以根据HTTP状态码来决定是否进行重试。
function requestWithRetry(options, retryCount = 3, delay = 1000) {
return new Promise((resolve, reject) => {
function makeRequest(attempt = 1) {
uni.request({
...options,
success(res) {
// 如果状态码是2xx,表示请求成功
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res);
} else {
// 处理非2xx的状态码
handleNonSuccessStatusCode(res, attempt);
}
},
fail(err) {
if (attempt >= retryCount) {
reject(err);
return;
}
console.warn(`第 ${attempt} 次请求失败,将在 ${delay}ms 后重试...`);
setTimeout(() => {
makeRequest(attempt + 1);
}, delay);
}
});
}
function handleNonSuccessStatusCode(res, attempt) {
const statusCode = res.statusCode;
// 只对某些特定的状态码进行重试
if ([500, 502, 503, 504].includes(statusCode)) {
if (attempt < retryCount) {
console.warn(`状态码 ${statusCode},将在 ${delay}ms 后重试...`);
setTimeout(() => {
makeRequest(attempt + 1);
}, delay);
} else {
reject(res);
}
} else {
// 对于其他状态码,直接拒绝
reject(res);
}
}
makeRequest(); // 第一次请求
});
}
错误码表
HTTP状态码 | 描述 | 是否重试 |
---|---|---|
200-299 | 成功 | ✅ |
400 | 请求无效 | ❌ |
401 | 未授权 | ❌ |
403 | 禁止访问 | ❌ |
404 | 资源未找到 | ❌ |
500 | 内部服务器错误 | ✅ |
502 | 网关错误 | ✅ |
503 | 服务不可用 | ✅ |
504 | 网关超时 | ✅ |
结合async/await
简化代码
如果你喜欢使用async/await
来编写异步代码,那么我们可以进一步简化代码结构。以下是结合async/await
的版本:
async function requestWithRetry(options, retryCount = 3, delay = 1000) {
for (let attempt = 1; attempt <= retryCount; attempt++) {
try {
const res = await new Promise((resolve, reject) => {
uni.request({
...options,
success(res) {
resolve(res);
},
fail(err) {
reject(err);
}
});
});
// 检查状态码
if (res.statusCode >= 200 && res.statusCode < 300) {
return res;
} else {
handleNonSuccessStatusCode(res, attempt);
}
} catch (err) {
if (attempt === retryCount) {
throw err; // 达到最大重试次数,抛出错误
}
console.warn(`第 ${attempt} 次请求失败,将在 ${delay}ms 后重试...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
// 使用示例
try {
const res = await requestWithRetry({
url: 'https://example.com/api/data',
method: 'GET'
});
console.log('最终请求成功:', res.data);
} catch (err) {
console.error('请求失败,已达到最大重试次数:', err);
}
总结
通过今天的分享,我们学会了如何在UniApp中实现request
请求的自动重试机制。我们不仅实现了基本的重试功能,还根据HTTP状态码进行了优化,确保只对可重试的错误进行重试。最后,我们还使用了async/await
来简化代码结构,让代码更加简洁易读。
希望这篇文章对你有所帮助!如果你有任何问题或建议,欢迎在评论区留言。😊
下次见!🌟
参考资料:
- MDN Web Docs – Fetch API
- Mozilla Developer Network – Error Handling in JavaScript
- Google Developers – Best Practices for Handling Network Errors
祝你编码愉快!🚀