Dart中的异步
最近在写Flutter,结果发现Dart的异步编程还和我目前学过的都不太一样,简单总结一下。
Future
什么是 Future
Future
就是一个Future<T>
对象,代表就是一个异步操作返回的结果,类型是T
如果返回的是不可用的值,则应该为Future<void>
举个例子
1 |
|
输出结果
1 | test1:2019-02-03 03:03:41.206838 |
这就是Future
的用法,其中用到了then
,如果需要使用链式编程,可以这样
1 | expensiveA() |
async / await
Dart
在1.9后,新加了两个关键字,async
和await
,即使不用Future
也能让异步编程看起来就像同步编程一样
上面的例子改成使用async
和await
1 | void main() { |
同样的输出效果
就相当于直接从Future
获取到了值,这样与原来不同的是,在await
执行后的代码都被延时后执行,这样也可以使用await
来保证执行顺序
1 | main() async { |
保证了执行顺序是 A -> B -> C
Dart
中的异步编程除了Future
还有Stream
,接下来我们看一下Stream
,Stream
在函数式编程中非常常见
Streams
什么是Stream
一个Stream
就是数据的一个异步的序列(数据流),序列用户生成的事件或者从文件读取的数据
怎么生成一个stream
呢,我们来看一下yield
关键词
yield
yeild
在异步编程会生成一个stream
,需要用async*
来标识,yield
的功能可以理解成一个叠加器,会不断累积前面的结果,加入新的数据,最后返回一个包含所有结果的容器
1 | Stream<int> testYield() async* { |
如果在yield
在同步方法中使用会怎么样,那生成的就不是stream
,而是一个Iterable
对象
Iterable
使用yield
必须用sync*
来标识,然后不能在
1 | test() { |
yield*
如果我们要使用递归,对yield
的结果进行yield
会怎么样,看这个例子
1 | void main() { |
输出结果
1 | (9, (8, (7, (6, (5, (4, (3, (2, (1, ()))))))))) |
这并不是我们想要的结果,看来对yield
的结果进行yield
则是直接把yield
生成的容器进行了yield
,我们需要把yield
生成容器的结果进行累加,则需要使用 yield*
修改为
1 | void main() { |
这样就能达到我们想要的结果了。