Dart语言-异步编程

一、Dart 异步编程基础

Dart 是一门单线程的语言,它通过异步操作来执行耗时任务,从而可以在等待一个操作完成的同时进行别的操作。常见的异步操作包括通过网络获取数据、写入数据库、从文件读取数据等。要在Dart中执行异步操作,可以使用Future类和asyncawait关键字。

二、Future 类

在 Dart 中,执行异步操作的核心是 Future 类。Future<T> 表示一个 T 类型的异步操作结果。如果异步操作不需要结果,则类型为 Future<void>

Future 工厂构造函数Future 的工厂构造函数接收一个 Dart 函数作为参数,这个函数没有参数,返回值是 FutureOr<T> 类型。可以根据返回的Future进行后续操作。

void main() {
  Future((){
    print("future run");
  });
  print("future test start");
}

//打印输出
//future test start
//future run

三、async和await关键字的运用

  • async关键字:标记一个函数为异步函数,使其返回一个Future对象。
  • await关键字:用于等待一个Future完成。它只能出现在异步函数内部,可以暂停当前函数的执行,直到Future完成,但不会阻塞事件循环,能够让我们可以像写同步代码那样来执行异步任务而不使用回调的方式。
  • async/await的实质:它们是Dart语言异步支持的语法糖,最终会被转化为Future的调用链。
main() async{
  void runFuture() async {
    var result =await Future.value(1);
    print("futrure result $result");
  }
  runFuture();
  print("runFuture()执行之后打印。");
}
//打印结果为:
//runFuture()执行之后打印。
//futrure result 1

四、事件队列与微任务队列的机制

Dart中,实际上有两种队列:

  • 事件队列(Event Queue):包含所有外来事件,如I/O操作、鼠标事件、绘制事件等。

    正常情况下,声明一个 Future 时,Dart 会将异步任务的函数执行体放入event queue,然后继续同步执行后续的代码。当同步执行的代码执行完毕后,event loop会按照加入event queue的顺序(即声明顺序),依次取出事件,最后同步执行 Future 的函数体及后续的操作。

  • 微任务队列(Microtask Queue):优先级高于事件队列,用于存放短时间内会完成的异步任务。主要由Dart内部产生。
    可以使用scheduleMicrotask或者Future.microtask来创建一个微任务去执行。
    如果Future已经执行完毕了,再来获取到这个Future的引用,然后再继续调用then()方法。那么此时,Dart会将后续加入的then()方法体放入microtask queue,尽快执行。

在每次事件循环中,Dart会先处理微任务队列中的任务,然后再处理事件队列中的任务。如果微任务队列中有太多任务,可能会阻塞事件队列中的任务,导致触摸、绘制等外部事件卡顿。

五、Future的处理方式

Future.value()

创建一个返回指定value值的Future

Future.delayed()

创建一个延迟执行的Future。传参接受一个Duration对象,传入延时时间;再传入方法体执行延时后的操作。

 void delayFuture() async {
    Future.delayed(Duration(milliseconds: 3000), () {
      print("delayed Future");
    });
  }
Future结果的处理方式

Future.then()

用于注册一个Future完成时要调用的回调,可以链式调用处理多个异步操作的结果。

void testFuture() async {
    Future.value(1).then((value) {
      return Future.value(value + 2);
    }).then((value) {
      return Future.value(value + 3);
    }).then(print);
}
Future异常的处理方式

Future.catchError:注册一个回调,来捕捉Futureerror

then中的回调onError

Future.catchError回调只处理原始Future抛出的错误

onError只能处理当前Future的错误

Future.error('Future 发生错误啦!').then((_) {
      throw 'new error';
    }).catchError((error) {
      print('error: $error');
      throw 'new error2';
    }).then(print, onError:(error) {
      print("handle new error: $error");
    });

Future.whenComplete():无论Future成功还是失败,都会执行的回调,用于执行一些清理工作或日志记录等。

FUture.timeout:为Future设置超时时间,超出时间后Future会抛出TimeoutException`

void testFuture() async {
    new Future.delayed(new Duration(seconds: 2), () {
      return 1;
    }).timeout(new Duration(seconds:1)).then(print).catchError(print);
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容