Flutter教程实现网络请求超时重试

在Flutter开发中,如何实现网络请求的超时重试机制?目前使用Dio发送请求时,当网络不稳定会出现超时失败,希望能自动重试3次,每次间隔2秒。有没有成熟的方案可以封装成通用方法?需要注意哪些细节(比如重试时保持请求参数一致、避免重复提交)?最好能提供带异常处理的实际代码示例。

3 回复

以下是一个简单的 Flutter 网络请求超时重试的实现:

  1. 引入依赖:http
  2. 使用 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');
  }
}

关键点说明:

  1. 使用DioconnectTimeoutreceiveTimeout设置超时时间
  2. 通过try-catch捕获DioException,特别处理超时相关错误类型
  3. 重试前添加延迟避免立即重试造成服务器压力
  4. 达到最大重试次数后抛出异常

进阶优化建议:

  • 可以添加指数退避策略(每次重试间隔时间加倍)
  • 针对特定HTTP状态码(如503)也进行重试
  • 使用cancelToken支持取消请求

这个方案在大多数网络请求场景下都能很好地工作,兼顾了用户体验和服务器压力。

回到顶部