【Flutter】Future 异步编程 ( 简介 | then 方法 | 异常捕获 | async、await 关键字 | whenComplete 方法 | timeout 方法 )





一、Future 简介



Future 指的是在 将来某个时刻结果 , 可以是一个值 , 也可以是一个报错信息 ;

借助 Future 可以实现异步操作 ;


Future 是在 dart:async 包中的类 , 系统会默认导入该包中的类 , 直接使用即可 , 不需要刻意导入 ;


Future 有两种状态 :

  • ① 执行中 , Pending 状态 ;
  • ② 执行结果 , Complete 状态 ;




二、Future.then 使用



调用 then 方法 , 可以在该方法中 , 获取 Future 中的值 , 其类型是 Future 泛型中的类型 ;

调用 testFuture 方法后 , 调用 then 方法 , 可以获取 testFuture 方法返回的 String 字符串 , 就是 s 参数 , 打印该字符串 ;

Future<String> testFuture() {
  return Future.value('success');
}

main() {
  testFuture().then((s) {
    print(s);
  });
}

Future 的 then 方法原型如下 :

  /// Register callbacks to be called when this future completes.
  ///
  /// When this future completes with a value,
  /// the [onValue] callback will be called with that value.
  /// If this future is already completed, the callback will not be called
  /// immediately, but will be scheduled in a later microtask.
  ///
  /// If [onError] is provided, and this future completes with an error,
  /// the `onError` callback is called with that error and its stack trace.
  /// The `onError` callback must accept either one argument or two arguments
  /// where the latter is a [StackTrace].
  /// If `onError` accepts two arguments,
  /// it is called with both the error and the stack trace,
  /// otherwise it is called with just the error object.
  /// The `onError` callback must return a value or future that can be used
  /// to complete the returned future, so it must be something assignable to
  /// `FutureOr<R>`.
  ///
  /// Returns a new [Future]
  /// which is completed with the result of the call to `onValue`
  /// (if this future completes with a value)
  /// or to `onError` (if this future completes with an error).
  ///
  /// If the invoked callback throws,
  /// the returned future is completed with the thrown error
  /// and a stack trace for the error.
  /// In the case of `onError`,
  /// if the exception thrown is `identical` to the error argument to `onError`,
  /// the throw is considered a rethrow,
  /// and the original stack trace is used instead.
  ///
  /// If the callback returns a [Future],
  /// the future returned by `then` will be completed with
  /// the same result as the future returned by the callback.
  ///
  /// If [onError] is not given, and this future completes with an error,
  /// the error is forwarded directly to the returned future.
  ///
  /// In most cases, it is more readable to use [catchError] separately,
  /// possibly with a `test` parameter,
  /// instead of handling both value and error in a single [then] call.
  ///
  /// Note that futures don't delay reporting of errors until listeners are
  /// added. If the first `then` or `catchError` call happens
  /// after this future has completed with an error,
  /// then the error is reported as unhandled error.
  /// See the description on [Future].
  Future<R> then<R>(FutureOr<R> onValue(T value), {Function? onError});

then 方法的第一个参数 FutureOr<R> onValue(T value) 就是 Future 的 onValue 代表的值 , 类型是 Future 泛型类型 R ;

then 方法的第二个参数 {Function? onError} 是可选的 , 用于捕获异常的方法 ;





三、Future 异常捕获



方式一 : then 方法传入 onError 参数 ;

在执行 返回值是 Future 类型的 testFuture 方法时 , 在 then 方法中 , 第二个参数 onError

Future<String> testFuture() {
  return Future.value('success');
}

main() {
  testFuture().then((s) {
    print(s);
  }, onError: (e) {
    print('onError:');
    print(e);
  });
}

方式二 : 继续链式调用 , 在 then 方法后 , 继续调用 Future 的 catchError 方法 ;

Future<String> testFuture() {
  return Future.value('success');
}

main() {
  testFuture().then((s) {
    print(s);
  }).catchError((e) {
    print('catchError:');
    print(e);
  });
}

注意 : 上述两个方法只能二选其一 , 如果都设置了 , 那么只有 方式一 生效 , 方式二 会被覆盖 ;





四、Dart 练习网站



https://dartpad.dartlang.org/ 网站 , 练习 Dart 语言 ;





五、async、await 关键字



async 关键字一般用作 方法的后缀 , 被修饰的方法的 返回值必须是 Future 类型的 ;

方法执行时 , 以 同步的形式 执行到 await 关键字位置 , 然后 挂起 , 等待后续异步方法执行 ;

异步任务执行完毕后 , await 之后的代码开始执行 ;





六、whenComplete 方法



在 Future 执行快要结束时 , 如果想要执行一些任务 , 可以在链式调用时 , 调用 Future 的 whenComplete 方法 ;

该方法类似于 try … catch … finally 中的 finally 代码块 , 是必定执行的代码 , 即使出险错误 , 也会执行该代码 ;

Future<String> testFuture() {
  return Future.value('success');
}

main() {
  testFuture().then((s) {
    print(s);
  }).catchError((e) {
    print('catchError:');
    print(e);
  }).whenComplete(() {
    print('whenComplete');
  });
}




七、timeout 方法



有的异步操作可能需要很长时间完成 , 这里为异步操作指定一个超时时间 ;

在 Future 链式调用时 , 调用 timeout 方法 , 设置超时时间 ;

void main() {
  /// 异步操作中会延迟 3 秒 , 超时时间 2 秒 
  new Future.delayed(new Duration(seconds: 3), () {
    return 1;
  }).timeout(new Duration(seconds: 2)).then(print).catchError(print);
}




八、相关资源



参考资料 :


重要的专题 :


博客源码下载 :

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Flutter网络请求dio封装是一种常用的网络请求框架,它可以帮助我们快速地进行网络请求,同时也可以提高我们的开发效率。在使用dio进行网络请求时,我们可以通过封装来简化代码,提高代码的可读性和可维护性。常见的封装方式有: 1. 封装请求方法:将网络请求的方法封装成一个函数,可以传入参数,方便调用。例如: ``` Future<Response> post(String url, Map<String, dynamic> data) async { try { Response response = await Dio().post(url, data: data); return response; } catch (e) { throw e; } } ``` 2. 封装请求拦截器:可以在请求前或请求后进行一些操作,例如添加请求头、打印请求日志等。例如: ``` class HttpUtil { static Dio dio = Dio(); static Future<Response> get(String url, {Map<String, dynamic> params}) async { dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { // 添加请求头 options.headers['Authorization'] = 'Bearer token'; return handler.next(options); }, onResponse: (response, handler) { // 打印请求日志 print('response: ${response.data}'); return handler.next(response); }, )); try { Response response = await dio.get(url, queryParameters: params); return response; } catch (e) { throw e; } } } ``` 3. 封装错误处理:可以统一处理网络请求的错误,例如网络异常、请求超时等。例如: ``` class HttpUtil { static Dio dio = Dio(); static Future<Response> get(String url, {Map<String, dynamic> params}) async { try { Response response = await dio.get(url, queryParameters: params); return response; } on DioError catch (e) { if (e.type == DioErrorType.CONNECT_TIMEOUT) { throw '请求超时'; } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) { throw '响应超时'; } else if (e.type == DioErrorType.RESPONSE) { throw '请求异常,状态码:${e.response.statusCode}'; } else if (e.type == DioErrorType.CANCEL) { throw '请求取消'; } else { throw '网络异常'; } } } } ``` 通过封装,我们可以让代码更加简洁、易读、易维护,同时也可以提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值