Flutter教程实现网络请求超时重试
在Flutter开发中,如何实现网络请求的超时重试机制?目前使用Dio发送请求时,当网络不稳定会出现超时失败,希望能自动重试3次,每次间隔2秒。有没有成熟的方案可以封装成通用方法?需要注意哪些细节(比如重试时保持请求参数一致、避免重复提交)?最好能提供带异常处理的实际代码示例。
3 回复
以下是一个简单的 Flutter 网络请求超时重试的实现:
- 引入依赖:
http
。 - 使用
Future.retry
实现重试逻辑。
import 'package:http/http.dart' as http;
import 'dart:async';
Future<http.Response> fetchWithRetry(String url, {int retries = 3}) async {
try {
return await Future.retry(
() => http.get(Uri.parse(url)).timeout(Duration(seconds: 5)),
maxAttempts: retries,
onRetry: (e) {
print("请求失败,即将重试: $e");
},
);
} catch (e) {
print("所有重试均失败: $e");
throw e;
}
}
void main() async {
final response = await fetchWithRetry('https://example.com');
print(response.body);
}
解释:
http.get
发起网络请求。timeout(Duration(seconds: 5))
设置超时时间为 5 秒。Future.retry
允许重试指定次数(这里为 3 次)。onRetry
在每次重试前执行回调,可以记录日志等。
这样就可以优雅地处理网络请求超时并进行重试了。
更多关于Flutter教程实现网络请求超时重试的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
以下是一个简单的 Flutter 实现网络请求超时重试的代码示例。我们使用 http
包发起请求,并通过 Future.delayed
实现重试机制。
import 'package:http/http.dart' as http;
import 'dart:async';
Future<void> fetchWithRetry(String url, {int maxRetries = 3}) async {
int retryCount = 0;
while (retryCount < maxRetries) {
try {
print('尝试第 ${retryCount + 1} 次请求...');
final response = await http.get(Uri.parse(url)).timeout(Duration(seconds: 5));
if (response.statusCode == 200) {
print('请求成功: ${response.body}');
return;
}
} catch (e) {
print('请求失败: $e');
}
retryCount++;
await Future.delayed(Duration(seconds: 2)); // 等待2秒后重试
}
print('达到最大重试次数,请求失败');
}
void main() async {
String url = "https://jsonplaceholder.typicode.com/posts";
await fetchWithRetry(url);
}
上述代码中,我们设置了最大重试次数为3次,每次请求超时时间为5秒。如果请求失败,会等待2秒后重试,直到达到最大重试次数或请求成功。
在Flutter中实现网络请求超时重试功能,可以使用dio
库(最流行的HTTP客户端)配合重试逻辑。以下是完整实现方案:
import 'package:dio/dio.dart';
// 带超时重试的网络请求
Future<Response> requestWithRetry({
required String url,
int maxRetries = 3,
int timeoutMs = 5000,
}) async {
final dio = Dio(BaseOptions(
connectTimeout: Duration(milliseconds: timeoutMs),
receiveTimeout: Duration(milliseconds: timeoutMs),
));
for (int attempt = 1; attempt <= maxRetries; attempt++) {
try {
final response = await dio.get(url);
return response;
} on DioException catch (e) {
if (e.type == DioExceptionType.connectionTimeout ||
e.type == DioExceptionType.receiveTimeout ||
e.type == DioExceptionType.sendTimeout) {
if (attempt == maxRetries) rethrow;
await Future.delayed(const Duration(seconds: 1)); // 延迟1秒后重试
continue;
}
rethrow; // 非超时错误直接抛出
}
}
throw Exception('Max retries reached');
}
// 使用示例
void fetchData() async {
try {
final response = await requestWithRetry(
url: 'https://api.example.com/data',
maxRetries: 3,
timeoutMs: 3000,
);
print(response.data);
} catch (e) {
print('Request failed: $e');
}
}
关键点说明:
- 使用
Dio
的connectTimeout
和receiveTimeout
设置超时时间 - 通过try-catch捕获
DioException
,特别处理超时相关错误类型 - 重试前添加延迟避免立即重试造成服务器压力
- 达到最大重试次数后抛出异常
进阶优化建议:
- 可以添加指数退避策略(每次重试间隔时间加倍)
- 针对特定HTTP状态码(如503)也进行重试
- 使用
cancelToken
支持取消请求
这个方案在大多数网络请求场景下都能很好地工作,兼顾了用户体验和服务器压力。