做者 | 弗拉德
来源 | 弗拉德(公众号:fulade_me)编程
Dart 代码库中有大量返回Future
或Stream
对象的函数,这些函数都是异步的,它们会在耗时操做执行完毕前直接返回而不会等待耗时操做执行完毕。async
和await
关键字用于实现异步编程,而且让你的代码看起来就像是同步的同样。网络
能够经过下面两种方式,得到Future
执行完成的结果:异步
async
和await
;Future API
;使用async
和await
的代码是异步的,可是看起来有点像同步代码。例如,下面的代码使用await
等待异步函数的执行结果。async
await lookUpVersion();
必须在带有async
关键字的异步函数中使用 await
:ide
Future checkVersion() async { var version = await lookUpVersion(); // 使用 version 继续处理逻辑 }
尽管异步函数能够处理耗时操做,可是它并不会等待这些耗时操做完成,异步函数执行时会在其遇到第一个 await
表达式的时候返回一个Future
对象,而后等待await
表达式执行完毕后继续执行。异步编程
使用try
、catch
以及finally
来处理使用await
致使的异常:函数
try { version = await lookUpVersion(); } catch (e) { // 没法找到版本时作出的反应 }
你能够在异步函数中屡次使用await
关键字。例如,下面代码中等待了三次函数结果:code
var entrypoint = await findEntrypoint(); var exitCode = await runExecutable(entrypoint, args); await flushThenExit(exitCode);
await
表达式的返回值一般是一个Future
对象;
若是不是的话也会自动将其包裹在一个Future
对象里。Future
对象表明一个"承诺",await
表达式会阻塞直到须要的对象返回。对象
若是在使用await
时致使编译错误,请确保await
在一个异步函数中使用。例如,若是想在main()
函数中使用await
,那么main()
函数就必须使用async
关键字标识。事件
Future main() async { checkVersion(); print('在 Main 函数中执行:版本是 ${await lookUpVersion()}'); }
定义异步函数只需在普通方法上加上async
关键字便可。
将关键字async
添加到函数并让其返回一个Future
对象。假设有以下返回String
对象的方法:
String lookUpVersion() => '1.0.0';
将其改成异步函数,返回值是Future
:
Future<String> lookUpVersion() async => '1.0.0';
注意,函数体不须要使用Future API
。若有必要,Dart
会建立Future
对象。
若是函数没有返回有效值,须要设置其返回类型为 Future<void>
Stream
也是用于接收异步事件数据,和Future
不一样的是,它能够接收多个异步操做的结果(成功或失败)。 也就是说,在执行异步任务时,能够经过屡次触发成功或失败事件来传递结果数据或错误异常。Stream
经常使用于会屡次读取数据的异步任务场景,如网络内容下载、文件读写等。举个例子:
Stream.fromFutures([ // 1秒后返回结果 Future.delayed(new Duration(seconds: 1), () { return "hello 1"; }), // 抛出一个异常 Future.delayed(new Duration(seconds: 2),(){ throw AssertionError("Error"); }), // 3秒后返回结果 Future.delayed(new Duration(seconds: 3), () { return "hello 3"; }) ]).listen((data){ print(data); }, onError: (e){ print(e.message); },onDone: (){ });
上面的代码依次会输出:
hello 1 Error hello 3