10_Dart异步支持

Dart库中有非常多的函数返回Future对象或Stream对象。这些函数是异步的:在可能耗时的操作(例如I/O)操作的语句之后不等到操作执行完成就返回。

async和await关键字支持异步编程,允许您编写类似于同步代码的异步代码。

处理Futures

当你需要一个完整的Futures的结果时,你有两个选择:

  • 使用async和await
  • 使用Future的API,如[库的引导]中描述的一样。

使用async和await的代码虽然是异步的,但是看起来很像同步代码。例如,以下代码使用await来等待异步函数执行的结果:

await lookUpVersion();
// 要使用await必须是对一个使用async标注的异步函数:

Future checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}

注意:尽管异步函数可能执行耗时的操作,但它不会等待这些操作。相反,异步函数一直执行直到遇到第一个await表达式([查看详细信息])。然后它返回一个Futures的对象,只有在await表达式完成之后才恢复执行。

使用try,catch和finally来处理使用await的代码中的错误:

try {
  version = await lookUpVersion();
} catch (e) {
  // React to inability to look up the version
}

你可以在异步函数中多次使用await。例如,以下代码执行了三次await来获取函数的结果。

var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);

在await表达式中,表达式的值通常是一个Future对象。如果不是,那么这个值将被自动包装成Future。Futrue对象指示返回结果一定是一个对象。表达式的值就是被返回的对象。await表达式会让程序执行挂起,直到返回的对象可用。

如果在使用await时出现编译时错误,请确保await在异步函数中 。例如,要在应用程序的main()函数中使用wait, main()的主体必须标记为async:

Future main() async {
  checkVersion();
  print('In main: version is ${await lookUpVersion()}');
}

声明异步函数

异步函数是函数体被用async修饰符标记的函数。 向函数中添加async关键字将使其返回一个Future。例如,请思考下例中返回一个字符串的同步函数:

String lookUpVersion() => '1.0.0';

如果你将他改变成一个异步函数,他的返回值将是一个Future:

Future lookUpVersion() async => '1.0.0';

注意,函数的主体不需要使用Future的API。如果需要,Dart将创建Future的对象。 如果您的函数没有返回一个有用的值,那么将其返回Future类型。

处理流(Stream)

当您需要从Stream获取值时,您有两个选择:

  • 使用async和异步的for循环(await for)
  • 使用Stream API,如[库的引导]中的描述

注意:在使用await for之前,请确保它使代码更清晰,并且您确实希望等待流(Stream)的所有结果。例如,您通常不应该为UI事件侦听器使用await,因为UI框架会发送无穷无尽的事件流。

异步for循环有以下形式:

await for (varOrType identifier in expression) {
  // Executes each time the stream emits a value.
}

表达式的值必须具有Stream类型。执行过程如下:

  1. 等待流发出值。
  2. 执行for循环的主体,并将变量设置为发出的值。
  3. 重复1和2,直到流关闭。
  4. 要停止侦听流,您可以使用break或return语句,该语句将跳出for循环,并从流中取消订阅。

如果在实现异步for循环时出现编译时错误,请确保await在异步函数中。例如,要在应用程序的main()函数中使用异步For循环,main()的主体必须标记为async:

Future main() async {
  // ...
  await for (var request in requestServer) {
    handleRequest(request);
  }
  // ...
}

有关异步编程的更多信息,请参阅[库引导文档]的dart:async部分。还可以参阅文章[Dart语言异步支持:阶段1]和[Dart语言异步支持:阶段2]和[Dart语言规范]。

你可能感兴趣的:(10_Dart异步支持)