Dart语言基础(异步支持)

Dart类库有非常多的返回Future或者Stream对象的函数。 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作,网络操作等。而不是等到这个操作完成。

asyncawait关键词支持了异步编程,允许您写出和同步代码很像的异步代码。

Future

Future与JavaScript中的Promise非常相似,表示一个异步操作的最终完成(或失败)及其结果值的表示。简单来说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。一个Future只会对应一个结果,要么成功,要么失败。
值得注意的时,Future的所有API返回值仍然时一个Future对象,所有非常适用于链式调用

Future 常用API
Future.then

下面示例使用一个2s演示模拟耗时操作,在程序开始运行2s后打印出”hello world!“

main() {
  Future.delayed(new Duration(seconds: 2),(){
    return "hello world!";
  }).then((data){ //.then接收异步结果并打印
    print(data);
  });
}
Future.catchError

如果异步任务发生错误,可以使用 Future.catchErrror 来捕获异常:

  Future.delayed(new Duration(seconds: 2),(){
    throw Exception("My Exception");
  }).then((data){
    //执行成功会走到这里  
    print("success");
  }).catchError((e){
    //执行失败会走到这里  
    print(e);
  });

我们在异步任务中抛出了一个异常,then的回调函数将不会被执行,取而代之的是 catchError回调函数将被调用, then方法还有一个可选参数onError,我们也可以它来捕获异常:

Future.delayed(new Duration(seconds: 2),(){
    throw Exception("My Exception");
  }).then((data){
    //执行成功会走到这里  
    print("success");
  }, onError: (e) {
    print("onError: $e");
  }).catchError((e){
    //执行失败会走到这里  
    print("catchError: $e");
  });

输出结果:

onError: Exception: My Exception

可以看出,在同一个Feture上,.onError 优先级高于 .catchError

Future.whenComplete

当我们遇到无论异步任务执行成功或失败都需要做一些事的场景,比如在网络请求前弹出加载对话框,在请求结束后关闭对话框。

 Future.delayed(new Duration(seconds: 2),(){
    throw Exception("My Exception");
   //throw AssertionError("Error");  
  }).then((data){
    //执行成功会走到这里  
    print("success");
  }).catchError((e){
    //执行失败会走到这里  
    print(e);
  }).whenComplete((){
    print("Complete");
  });
Future.wait

当运行结果依赖于有多个异步任务运行结果,比如我们有一个界面,需要先分别从IO和网络两个接口获取数据,两个接口均获取成功后才能进行UI处理,这个时候我们可以使用Future.wait来出来,它接受一个Future数组参数,只有数组中所有Future都执行成功后,才会触发then的成功回调,只要有一个Future执行失败,就会触发错误回调。
使用方法如下:

Future.wait([Future1,Future2])
  .then((){ 
  //处理成功  
  }).catchError((e){
  //处理失败
 });

举个例子:

 Future.wait([
  // 2秒后返回结果  
  Future.delayed(new Duration(seconds: 2), () {
    return "hello";
  }),
  // 4秒后返回结果  
  Future.delayed(new Duration(seconds: 4), () {
    return " world";
  })
  ]).then((results){
    print(results[0]+results[1]);
  }).catchError((e){
    print(e);
  });

通过上面学习,我们可以大概总结出Future的使用步骤:

  1. 创建Future对象
  2. 通过Future.then方法监听Future内部执行成功时的结果
  3. 通过Future.catchError监听Future内部失败或者异常时的错误信息
  4. 通过Future.whenComplete监听所有任务完成信息

async/await

Dart中的async/await 和JavaScript中的async/await功能和用法是一模一样的,如果你已经了解JavaScript中的async/await的用法,可以直接跳过本节。

  • async用来表示函数是异步的,定义的函数会返回一个Future对象,可以使用then方法添加回调函数。
  • await 后面是一个Future,表示等待该异步任务完成,异步完成后才会往下走;await必须出现在 async 函数内部
    使用async/await的目的是将一个异步流用同步的代码表示出来了
    修改下上面2s后打印 “hello world!” 的例子:
main() {
  getPrintData().then((data0)=>print(data0));
}

Future<String> getPrintData() async {
  String data =  await Future.delayed(new Duration(seconds: 2),(){
    return "hello world!";
  });
  return "要打印的数据: "+ data;
}

async/await都只是一个语法糖,编译器或解释器最终都会将其转化为一个Future的调用链。

Stream

Stream 也是用于接收异步事件数据,和Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。 也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。

 Stream.fromFutures([
    // 1秒后返回结果
    Future.delayed(new Duration(seconds: 1), () {
      return "hello world 1";
    }),
    // 抛出一个异常
    Future.delayed(new Duration(seconds: 2),(){
      throw AssertionError("Error");
    }),
    // 3秒后返回结果
    Future.delayed(new Duration(seconds: 3), () {
      return "hello world 3";
    })
  ]).listen((data){
    print(data);
  }, onError: (e){
    print(e.message);
  },onDone: (){
    print("Steam done");
  });

输出结果:

hello world 1
Error
hello world 3
Steam done

Dart的异步机制

该部分为进阶部分,可以直接跳过,后续需要在阅读。
不同操作语言处理耗时任务有不同的处理机制:

  • 多线程,开启一个新的线程,在新线程中进行异步操作,在通过线程间通信,将数据同主线程共享。Java和C++使用这种方式。
  • 单线程+事件循环,JavaScript和Dart就是使用这种方式。
    有关Dart异步机制,请参考 Dart异步处理机制

参考
https://book.flutterchina.club/chapter1/dart.html
https://segmentfault.com/a/1190000020398241

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值