面试题答案
一键面试- 引入依赖:
在
pubspec.yaml
文件中确保已引入dio
库:
dependencies:
dio: ^[具体版本号]
然后运行flutter pub get
。
2. 定义重试策略:
- 超时错误重试策略: 通常可以设置一个固定的重试次数,比如3次,每次重试间隔一定时间(如2秒)。
- 连接失败重试策略: 与超时类似,但可能重试次数可以更多一些,例如5次,重试间隔可适当增加(如3秒)。
- 服务器错误重试策略: 对于一些常见的服务器错误(如500系列错误),可以尝试较少次数(如2次),间隔时间相对较短(如1秒)。
- 实现代码逻辑:
import 'package:dio/dio.dart';
class RetryInterceptor extends Interceptor {
int maxRetryCount = 3;
Duration retryDelay = const Duration(seconds: 2);
@override
void onError(DioError err, ErrorInterceptorHandler handler) async {
if (err.type == DioErrorType.connectTimeout ||
err.type == DioErrorType.sendTimeout ||
err.type == DioErrorType.receiveTimeout) {
// 超时错误重试
int retryCount = 0;
while (retryCount < maxRetryCount) {
retryCount++;
await Future.delayed(retryDelay);
try {
final response = await err.requestOptions.retryWith();
return handler.resolve(response);
} catch (e) {
if (retryCount == maxRetryCount) {
return handler.reject(err);
}
}
}
} else if (err.type == DioErrorType.connectionError) {
// 连接失败重试
maxRetryCount = 5;
retryDelay = const Duration(seconds: 3);
int retryCount = 0;
while (retryCount < maxRetryCount) {
retryCount++;
await Future.delayed(retryDelay);
try {
final response = await err.requestOptions.retryWith();
return handler.resolve(response);
} catch (e) {
if (retryCount == maxRetryCount) {
return handler.reject(err);
}
}
}
} else if (err.response != null && (err.response.statusCode! >= 500 && err.response.statusCode! < 600)) {
// 服务器错误重试
maxRetryCount = 2;
retryDelay = const Duration(seconds: 1);
int retryCount = 0;
while (retryCount < maxRetryCount) {
retryCount++;
await Future.delayed(retryDelay);
try {
final response = await err.requestOptions.retryWith();
return handler.resolve(response);
} catch (e) {
if (retryCount == maxRetryCount) {
return handler.reject(err);
}
}
}
} else {
return handler.reject(err);
}
}
}
extension RetryExtension on RequestOptions {
Future<Response> retryWith() async {
final dio = Dio();
return dio.request(
path,
data: data,
queryParameters: queryParameters,
options: this,
);
}
}
- 使用重试拦截器:
void main() async {
final dio = Dio();
dio.interceptors.add(RetryInterceptor());
try {
final response = await dio.get('https://example.com/api');
print(response.data);
} catch (e) {
print('请求失败: $e');
}
}
上述代码通过自定义RetryInterceptor
拦截器,根据不同类型的DioError
制定了不同的重试策略,并通过扩展RequestOptions
类实现了重试功能。在main
函数中,将RetryInterceptor
添加到Dio
的拦截器中,从而使网络请求具备重试机制。