写在前面

在Dio官方的GitHub上有关于token拦截器的例子,但在目前3.0.7的版本里,onError里面有一个问题,就是 dio.interceptors.errorLock.lock() 似乎无效,即使调用了该方法,照样onError里还是能使得多个错误进入。

Example:
interceptor_lock.dart

相关问题:
Token拦截器里的onError,使用 dio.interceptors.errorLock.lock() 无效 #877

Locking interceptors doesn’t work when multiple requests are enqueued #590

在进行一些尝试后,在它的Example代码上做了补充,以在当前处理该问题,待官方是否之后修复该问题。

代码

main() async {
  Dio dio = Dio();
  Dio tokenDio = Dio();
  String csrfToken;
  dio.options.baseUrl = "http://www.dtworkroom.com/doris/1/2.0.0/";
  // 添加一个Future
  Future<Null> _lockFuture;

  tokenDio.options = dio.options;
  dio.interceptors.add(InterceptorsWrapper(onError: (DioError error) {
    if (error.response?.statusCode == 401) {
      RequestOptions options = error.response.request;

      //放过第一个错误去刷新token,拦截之后的错误
      if (dio.interceptors.errorLock.locked) {
          if (_lockFuture != null) {
            await _lockFuture;
          }
        }
        
      if (csrfToken != options.headers["csrfToken"]) {
        options.headers["csrfToken"] = csrfToken;
        return dio.request(options.path, options: options);
      }
 
      dio.lock();
      dio.interceptors.responseLock.lock();
      dio.interceptors.errorLock.lock();
      // 初始化
      var completer = new Completer<Null>();
      _lockFuture = completer.future;
      
        return tokenDio.get("/token").then((d) {

        options.headers["csrfToken"] = csrfToken = d.data['data']['token'];
      }).whenComplete(() {
        dio.unlock();
        dio.interceptors.responseLock.unlock();
        dio.interceptors.errorLock.unlock();
       
        completer.complete();
        _lockFuture = null;
        
      }).then((e) {
        return dio.request(options.path, options: options);
      });
    }
    return error;
  }));

  _onResult(d) {
    print("request ok!");
  }

  await Future.wait([
    dio.get("/test?tag=1").then(_onResult),
    dio.get("/test?tag=2").then(_onResult),
    dio.get("/test?tag=3").then(_onResult)
  ]);
}
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐