1. import 'package:dio/dio.dart';
  2. void getHttp() async {
  3. try {
  4. var response = await Dio().get('http://www.google.com');
  5. print(response);
  6. } catch (e) {
  7. print(e);
  8. }
  9. }

Overview

dio-basic.png

Dio 底层是叫做 HttpClientAdapter 的抽象类,这个类只定义了一个方法 fetch ,通过 option 去调整请求的参数,上层是 DioMinix 的 Mixin 类,实现了 Get , Post 等方法对于fetch 的封装,并且完成了各个功能的接入,比如 FormData 类型的编码,Interperceptor 的调用等,

Interceptor

dio-interceptor.png

Interceptor 是 Dio 中的拦截器, Interceptor 需要定义三种方法 onRequest , onResponse , onError

定义好的 Interceptor 会进入到 Interceptors ,这个类型实现了 ListMixin 抽象类,也就是说可以像操作 List 一样操作它,那为什么不直接使用 List<Interceptor> 呢? Interceptors 除了包含 List 的功能以外,还可以通过 lock/unlock 来锁定,解锁拦截器,保证请求 / 响应的串行执行。由于 dart 没有提供 lock 函数,所以 Dio 就使用 Future 实现了 lock。

  1. class Lock {
  2. Future? _lock;
  3. late Completer _completer;
  4. bool get locked => _lock != null;
  5. void lock() {
  6. if (!locked) {
  7. _completer = Completer();
  8. _lock = _completer.future;
  9. }
  10. }
  11. void unlock() {
  12. if (locked) {
  13. _completer.complete();
  14. _lock = null;
  15. }
  16. }
  17. void clear([String msg = 'cancelled']) {
  18. if (locked) {
  19. _completer.completeError(msg);
  20. _lock = null;
  21. }
  22. }
  23. Future? enqueue(EnqueueCallback callback) {
  24. if (locked) {
  25. // we use a future as a queue
  26. return _lock!.then((d) => callback());
  27. }
  28. return null;
  29. }
  30. }

Cancel Token

Dio 支持 Cancel Token 的功能,Cancel Token 实际上就就是一个 Completer ,调用 cancel 的时候,会调用 Completer 的 complete 方法,
dio-cancel token.png

  1. CancelToken token = CancelToken();
  2. dio.get(url, cancelToken: token)
  3. .catchError((DioError err){
  4. if (CancelToken.isCancel(err)) {
  5. print('Request canceled! '+ err.message)
  6. }else{
  7. // handle error.
  8. }
  9. });
  10. // cancel the requests with "cancelled" message.
  11. token.cancel("cancelled");