【Dart】异步操作关键字:await、async、Future

先看一个模拟下载文件的例子:

void main(){
  print("main start at ${DateTime.now()}");
  download();//没有加await关键字表示当前线程不需要等待(不会阻塞)
  print("main end at ${DateTime.now()}");
}

void download() async {
  print("download start at ${DateTime.now()}");
  await new Future.delayed(const Duration(seconds: 5)); //当前线程休眠5秒
  print("download end at ${DateTime.now()}");
}
}

运行结果:

main start at 2019-06-02 12:49:20.421
download start at 2019-06-02 12:49:20.422
main end at 2019-06-02 12:49:20.423
download end at 2019-06-02 12:49:25.427

可以看到,调用download函数没加await关键字时,表示不会引起当前线程阻塞。

下面把download()函数前面加上await关键字:

void main() async{
  print("main start at ${DateTime.now()}");
  await download();//等待await操作
  print("main end at ${DateTime.now()}");
}

void download() async {
  print("download start at ${DateTime.now()}");
  await new Future.delayed(const Duration(seconds: 5)); //当前线程休眠5秒
  print("download end at ${DateTime.now()}");
}

执行结果:

main start at 2019-06-02 12:53:17.014
download start at 2019-06-02 12:53:17.015
download end at 2019-06-02 12:53:22.021
main end at 2019-06-02 12:53:22.022

可以看到,调用download函数前加了await关键字后,表示会等待download执行完毕,才会继续往下执行。
调用函数前面加上await表示,需要等待await操作(一般是耗时操作)执行完毕,才能顺序执行后面的语句。不加await表示,即使有await操作,也不会阻塞当前线程。

要说明的是,函数体内如果有await语句,那么这个函数声明后面就要加上async关键字修饰,否则编译会不通过。如果函数体内没有await调用语句,函数声明后面加上async也不会报错。

以上是不带返回值的情况,下面看看download函数加上返回值的例子。

download函数修改为:

Future<String> download() async { //声明async的函数,返回类型必须是Future类型。
  print("download start at ${DateTime.now()}");
  await new Future.delayed(const Duration(seconds: 5)); //当前线程休眠5秒
  print("download end at ${DateTime.now()}");
  return "Hi,I come from server!";//自动转成Future<Sring>类型
}

先看看调用download()函数时不加await操作是怎样的。

main函数修改成:

void main() async {
  
  print("main start at ${DateTime.now()}");
  
  Future<String> content = download(); //不等待await操作,返回值必须是Future不能是String否则编译报错。
  
  //添加监听回调,相当是给异步操作添加了listener
  content.then((string) {
    print("result[${DateTime.now()}]: $string"); //异步操作完成时执行
  });
  
  print("main end at ${DateTime.now()}");
}

执行结果:

main start at 2019-06-02 13:38:56.385
download start at 2019-06-02 13:38:56.386
main end at 2019-06-02 13:38:56.387
download end at 2019-06-02 13:39:01.389
result[2019-06-02 13:39:01.390]: Hi,I come from server!

下面看看调用download()函数时加了await操作是怎样的。

main()函数修改成:

void main() async {
  
  print("main start at ${DateTime.now()}");
  
  String content = await download(); //等待await操作
  //虽然download函数返回一个Future<String>对象,但是因为是加了await,所以不需要再用Future来接收返回值,可以直接使用String类型。
  
  print("result[${DateTime.now()}]: $content");
  
  print("main end at ${DateTime.now()}");
}

执行结果:

main start at 2019-06-02 13:41:15.421
download start at 2019-06-02 13:41:15.421
download end at 2019-06-02 13:41:20.425
result[2019-06-02 13:41:20.425]: Hi,I come from server!
main end at 2019-06-02 13:41:20.426

可以看到,加了await与不加await调用函数时,是有明显不同的。加了await相当于是一个同步任务。不加await调用函数,等于是一个异步任务,需要添加回调函数接收异步任务的结果。

原创文章 56 获赞 44 访问量 9万+

猜你喜欢

转载自blog.csdn.net/devnn/article/details/90738365