Dio: Token拦截器里的onError,使用 dio.interceptors.errorLock.lock() 无效

Created on 31 Jul 2020  ·  6Comments  ·  Source: flutterchina/dio

dio 3.0.7

我创建了个Token拦截器,在onError里处理当token过期时,进行刷新的逻辑。

当我只有一个请求时,过程还是正常的,但当有多个请求同时进行时,我按照Example的例子使用了dio.interceptors.errorLock.lock()
但我发现,即使使用了这个,其它请求同样也会因token失效的错误进入onError,导致dio.interceptors.errorLock.lock()多次被调用。似乎这个锁没有用。

它们不是应该在那里阻塞吗?直到我unlock?

Most helpful comment

3.0.10已修复

All 6 comments

I used my own completer to solve this .
```
//here
Future _lockFuture;

@override
onError(DioError error)  {
if (error.response?.statusCode == 401) {
  RequestOptions options = error.response.request;

   //here
   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();
   //here
   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();
    //here
    completer.complete();
    _lockFuture = null;

  }).then((e) {
    return dio.request(options.path, options: options);
  });
}
return error;

}));

590

拦截器锁的作用范围和dio实例是相关的,不同dio实例之间是相互隔离的,建议全局用同一个dio实例。如果业务场景需要创建多个dio实例,可以用你这种方法去同步多个dio实例。

拦截器锁的作用范围和dio实例是相关的,不同dio实例之间是相互隔离的,建议全局用同一个dio实例。如果业务场景需要创建多个dio实例,可以用你这种方法去同步多个dio实例。

你好,我当前是只有一个dio实例的,我用的是单例模式来包裹dio,我在onRequest里调用dio.lock(),确实其它一同发起的request都被lock住了,但在onError里调用dio.interceptors.errorLock.lock(),其它的error照样能进入onError()。

3.0.10已修复

3.0.10已修复
3.0.10还是有问题

Was this page helpful?
0 / 5 - 0 ratings