1. 自动重试机制
- 实现方式:利用
dio
的拦截器(Interceptors
)来实现。在请求拦截器中记录请求信息,在响应拦截器中判断响应状态码,如果是网络错误(如 408
请求超时、网络连接失败等),则进行重试。
import 'package:dio/dio.dart';
class RetryInterceptor extends Interceptor {
int maxRetryCount = 3;
@override
void onError(DioError err, ErrorInterceptorHandler handler) async {
if (err.type == DioErrorType.connectTimeout ||
err.type == DioErrorType.sendTimeout ||
err.type == DioErrorType.receiveTimeout) {
if (err.response?.statusCode == 408) {
int retryCount = 0;
while (retryCount < maxRetryCount) {
try {
final response = await dio.request(
err.requestOptions.path,
options: err.requestOptions,
);
return handler.resolve(response);
} catch (e) {
retryCount++;
}
}
}
}
return handler.next(err);
}
}
- 优点:
- 提高请求成功率,在网络不稳定时,能够自动尝试多次请求,增加请求成功的可能性。
- 对用户透明,无需用户手动操作重新请求,提升用户体验。
- 缺点:
- 增加服务器压力,多次重试可能会给服务器带来额外的负载。
- 可能导致请求时间过长,如果重试次数过多且每次重试间隔时间不合理,会使请求等待时间过长,影响用户体验。
- 适用场景:适用于对请求成功率要求较高的场景,如支付请求、重要数据的获取请求等。
2. 优化请求队列
- 实现方式:可以使用 Dart 的
Queue
数据结构来管理请求队列。当网络状态良好时,从队列中按顺序取出请求并发送;当网络状态不佳时,暂停从队列中取出请求,直到网络恢复。同时,可以设置队列的最大长度,避免过多请求堆积。
import 'dart:collection';
import 'package:dio/dio.dart';
class RequestQueue {
final Queue<RequestOptions> _queue = Queue();
final Dio dio;
int maxQueueLength = 10;
bool isProcessing = false;
RequestQueue(this.dio);
void addRequest(RequestOptions options) {
if (_queue.length < maxQueueLength) {
_queue.add(options);
_processQueue();
}
}
Future<void> _processQueue() async {
if (isProcessing || _queue.isEmpty) return;
isProcessing = true;
while (!_queue.isEmpty) {
final options = _queue.removeFirst();
try {
await dio.request(options.path, options: options);
} catch (e) {
// 处理请求失败
}
}
isProcessing = false;
}
}
- 优点:
- 避免资源耗尽,通过限制请求队列长度,防止过多请求同时占用资源,如网络带宽、内存等。
- 有序处理请求,保证请求按照添加顺序依次执行,符合业务逻辑顺序。
- 缺点:
- 可能导致部分请求等待时间过长,如果队列前面的请求处理时间较长,后面的请求需要等待。
- 实现相对复杂,需要额外管理请求队列及处理网络状态变化对队列的影响。
- 适用场景:适用于资源有限的环境,如移动设备,且请求之间存在一定顺序要求的场景,如多个数据的连续上传请求。
3. 结合缓存策略
- 实现方式:利用
dio
的 CacheManager
来实现缓存策略。可以设置不同的缓存策略,如 CacheControl
中的 maxAge
(最大缓存时间)等。
import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
final dio = Dio();
final cacheOptions = CacheOptions(
store: MemCacheStore(),
policy: CachePolicy.request,
maxStale: const Duration(days: 7),
);
dio.interceptors.add(DioCacheInterceptor(options: cacheOptions));
- 优点:
- 减少不必要的网络请求,提高响应速度,对于频繁请求且数据变化不频繁的接口,可以直接从缓存中获取数据,节省网络流量和时间。
- 降低服务器负载,减少对服务器的请求次数,提高服务器的整体性能。
- 缺点:
- 数据可能过时,缓存的数据存在一定的时效性,如果在缓存有效期内数据在服务器端发生变化,客户端获取的是旧数据。
- 缓存管理复杂,需要合理设置缓存策略,如缓存时间、缓存清除机制等,否则可能导致缓存数据占用过多内存或缓存数据不一致等问题。
- 适用场景:适用于数据更新频率较低的场景,如一些配置信息的获取、静态页面数据的请求等。