Skip to content

Commit 7abcfd1

Browse files
committed
4.0.0-prev1
breaking change: **Interceptors:** Add `handler` for Interceptor APIs which can specify the subsequent interceptors processing logic more finely(whether to skip them or not))
1 parent 451d592 commit 7abcfd1

39 files changed

+1494
-1001
lines changed

README-ZH.md

+46-55
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截
1515

1616
```yaml
1717
dependencies:
18-
dio: ^4.0.0-beta7
18+
dio: ^4.0.0-prev1
1919
```
2020
21-
> 4.0 changelog 待补充
21+
> 如果你是dio 3.x 用户,想了解4.0的变更,请参考 [4.x更新列表](./migration_to_4.x.md)!
2222
2323
## 一个极简的示例
2424
@@ -336,27 +336,30 @@ print(response.statusCode);
336336

337337
## 拦截器
338338

339-
每个 Dio 实例都可以添加任意多个拦截器,他们组成一个队列,拦截器队列的执行顺序是FIFO。通过拦截器你可以在请求之前或响应之后(但还没有被 `then``catchError`处理)做一些统一的预处理操作。
339+
每个 Dio 实例都可以添加任意多个拦截器,他们组成一个队列,拦截器队列的执行顺序是FIFO。通过拦截器你可以在请求之前、响应之后和发生异常时(但还没有被 `then``catchError`处理)做一些统一的预处理操作。
340340

341341
```dart
342-
343342
dio.interceptors.add(InterceptorsWrapper(
344-
onRequest:(RequestOptions options) async {
345-
// 在请求被发送之前做一些事情
346-
return options; //continue
347-
// 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`对象或返回`dio.resolve(data)`。
348-
// 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义数据data.
343+
onRequest:(options, handler){
344+
// Do something before request is sent
345+
return hanlder.next(options); //continue
346+
// 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`,如`dio.resolve(response)`。
347+
// 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
349348
//
350-
// 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,或返回`dio.reject(errMsg)`,
349+
// 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如`dio.reject(error)`,
351350
// 这样请求将被中止并触发异常,上层catchError会被调用。
352351
},
353-
onResponse:(Response response) async {
354-
// 在返回响应数据之前做一些预处理
355-
return response; // continue
352+
onResponse:(response,handler) {
353+
// Do something with response data
354+
return handler.next(response); // continue
355+
// 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如`dio.reject(error)`,
356+
// 这样请求将被中止并触发异常,上层catchError会被调用。
356357
},
357-
onError: (DioError e) async {
358-
// 当请求失败时做一些预处理
359-
return e;//continue
358+
onError: (DioError e, handler) {
359+
// Do something with response error
360+
return handler.next(e);//continue
361+
// 如果你想完成请求并返回一些自定义数据,可以返回一个`Response`,如`dio.resolve(response)`。
362+
// 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
360363
}
361364
));
362365
```
@@ -365,21 +368,21 @@ dio.interceptors.add(InterceptorsWrapper(
365368

366369
```dart
367370
import 'package:dio/dio.dart';
368-
class CustomInterceptors extends InterceptorsWrapper {
371+
class CustomInterceptors extends Interceptor {
369372
@override
370-
Future onRequest(RequestOptions options) {
371-
print('REQUEST[${options?.method}] => PATH: ${options?.path}');
372-
return super.onRequest(options);
373+
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
374+
print('REQUEST[${options.method}] => PATH: ${options.path}');
375+
return super.onRequest(options, handler);
373376
}
374377
@override
375-
Future onResponse(Response response) {
376-
print('RESPONSE[${response?.statusCode}] => PATH: ${response?.request?.path}');
377-
return super.onResponse(response);
378+
Future onResponse(Response response, ResponseInterceptorHandler handler) {
379+
print('RESPONSE[${response.statusCode}] => PATH: ${response.request?.path}');
380+
return super.onResponse(response, handler);
378381
}
379382
@override
380-
Future onError(DioError err) {
381-
print('ERROR[${err?.response?.statusCode}] => PATH: ${err?.request?.path}');
382-
return super.onError(err);
383+
Future onError(DioError err, ErrorInterceptorHandler handler) {
384+
print('ERROR[${err.response?.statusCode}] => PATH: ${err.request.path}');
385+
return super.onError(err, handler);
383386
}
384387
}
385388
```
@@ -390,30 +393,14 @@ class CustomInterceptors extends InterceptorsWrapper {
390393

391394
```dart
392395
dio.interceptors.add(InterceptorsWrapper(
393-
onRequest:(RequestOptions options) {
394-
return dio.resolve('fake data')
396+
onRequest:(options, handler) {
397+
return handler.resolve(Response(requestOptions:options,data:'fake data'));
395398
},
396399
));
397400
Response response = await dio.get('/test');
398401
print(response.data);//'fake data'
399402
```
400403

401-
### 拦截器中支持异步任务
402-
403-
拦截器中不仅支持同步任务,而且也支持异步任务, 下面是在请求拦截器中发起异步任务的一个实例:
404-
405-
```dart
406-
dio.interceptors.add(InterceptorsWrapper(
407-
onRequest:(Options options) async{
408-
//...If no token, request token firstly.
409-
Response response = await dio.get("/token");
410-
//Set the token to headers
411-
options.headers["token"] = response.data["data"]["token"];
412-
return options; //continue
413-
}
414-
));
415-
```
416-
417404
### Lock/unlock 拦截器
418405

419406
你可以通过调用拦截器的 `lock()`/`unlock` 方法来锁定/解锁拦截器。一旦请求/响应拦截器被锁定,接下来的请求/响应将会在进入请求/响应拦截器之前排队等待,直到解锁后,这些入队的请求才会继续执行(进入拦截器)。这在一些需要串行化请求/响应的场景中非常实用,后面我们将给出一个示例。
@@ -422,16 +409,18 @@ dio.interceptors.add(InterceptorsWrapper(
422409
tokenDio = Dio(); //Create a new instance to request the token.
423410
tokenDio.options = dio.options.copyWith();
424411
dio.interceptors.add(InterceptorsWrapper(
425-
onRequest:(Options options) async {
412+
onRequest:(Options options, handler){
426413
// If no token, request token firstly and lock this interceptor
427414
// to prevent other request enter this interceptor.
428415
dio.interceptors.requestLock.lock();
429416
// We use a new Dio(to avoid dead lock) instance to request token.
430-
Response response = await tokenDio.get('/token');
431-
//Set the token to headers
432-
options.headers['token'] = response.data['data']['token'];
433-
dio.interceptors.requestLock.unlock();
434-
return options; //continue
417+
tokenDio.get('/token').then((response){
418+
//Set the token to headers
419+
options.headers['token'] = response.data['data']['token'];
420+
handler.next(options); //continue
421+
}).catchError((error, stackTrace) {
422+
handler.reject(error, true);
423+
}).whenComplete(() => dio.interceptors.requestLock.unlock());
435424
}
436425
));
437426
```
@@ -456,21 +445,23 @@ dio.interceptors.add(InterceptorsWrapper(
456445

457446
```dart
458447
dio.interceptors.add(InterceptorsWrapper(
459-
onRequest: (Options options) async {
448+
onRequest: (Options options, handler) async {
460449
print('send request:path:${options.path},baseURL:${options.baseUrl}');
461450
if (csrfToken == null) {
462451
print('no token,request token firstly...');
463452
//lock the dio.
464453
dio.lock();
465-
return tokenDio.get('/token').then((d) {
454+
tokenDio.get('/token').then((d) {
466455
options.headers['csrfToken'] = csrfToken = d.data['data']['token'];
467456
print('request token succeed, value: ' + d.data['data']['token']);
468457
print( 'continue to perform request:path:${options.path},baseURL:${options.path}');
469-
return options;
470-
}).whenComplete(() => dio.unlock()); // unlock the dio
458+
handler.next(options);
459+
}).catchError((error, stackTrace) {
460+
handler.reject(error, true);
461+
}) .whenComplete(() => dio.unlock()); // unlock the dio
471462
} else {
472463
options.headers['csrfToken'] = csrfToken;
473-
return options;
464+
handler.next(options);
474465
}
475466
}
476467
));

0 commit comments

Comments
 (0)