Skip to content

Flutter适时取消请求 提升应用性能 避免阻塞

应用实际运行中,不能保证请求在生命周期内100%得到执行。 一个继续中的请求,应该在用户关闭路由(组件)的过程中,被及时中断。或者在用户尝试重新发起请求前,废除现有的请求。
还有一种情况,便是前序的请求发生错误,那么要使得后续有前序依赖的请求,及时发生短路销毁。不必要的请求及时取消,无论是对客户端还是服务端都是有意义的 在业务中还能保证业务安全。

Flutter取消请求的实现方式Dio为例

如果你使用Dio或者类似的请求类,(任何现代的请求类都会支持的)你无需过度封装,仅调用自带的CancelToken即可轻松实现。

dart
/// Dio核心请求实现是这样的,注意看到CancelToken,虽然可以传入null,但你别这么懒
Future<Response<T>> request<T>(
  String path, {
  Object? data,
  Map<String, dynamic>? queryParameters,
  CancelToken? cancelToken,
  Options? options,
  ProgressCallback? onSendProgress,
  ProgressCallback? onReceiveProgress,
});


/// 实际发起请求时
final CancelToken cancelToken = CancelToken();
final response = await dio.request(
  '/test',
  data: {'id': 12, 'name': 'dio'},
  options: Options(method: 'GET'),
  cancelToken: cancelToken
);

上述的请求中,我们传入了cancelToken,他可以用来控制这个请求。在一个StatefulWidget中,我们可以在dispose中调用cancelToken.cancel()来取消请求。

dart
@override
void dispose() {
  cancelToken.cancel();
  super.dispose();
}

这样一来页面销毁时,我们便取消了请求,异步请求将不会因为组件的销毁,而持续运行。

请求队列

既然有了CancelToken,那么我们可以考虑将请求封装到一个队列中,当队列中的请求被取消时,我们便取消队列中的所有请求。所以我们手动实现一个CancelToken Group工具类,将所有队列请求托管与此,当前序请求发生错误时,批量执行cancelToken.cancel()即可轻而易举的完成。

dart
import 'package:dio/dio.dart';

class DioCancelTokenGroup {
  final List<DioCancelToken> _cancelTokens = [];

  void add(DioCancelToken cancelToken) {
    _cancelTokens.add(cancelToken);
  }

  void remove(DioCancelToken cancelToken) {
    _cancelTokens.remove(cancelToken);
  }

  void cancelAll(String reason) {
    for (final cancelToken in _cancelTokens) {
      cancelToken.cancel(reason);
    }
    _cancelTokens.clear();
  }
}

仅用于培训和测试,通过使用本站代码内容随之而来的风险与本站无关。版权所有,未经授权请勿转载,保留一切权利。
ICP备案号:滇ICP备15009214号-13   公安网备:滇公网安备 53312302000061号