面向Kotlin与Java开发者的Dart快速入门(十二)异步与并发

在这里插入图片描述

异步编程


Dart可以像C#或Javascript那样可以通过 async/await 实现异步逻辑

Future与async/await

与Js的async/awiatPromise的语法糖一样,Dart的async/awiat只不过是Future的语法糖,可以帮助我们的用同步的代码处理Future提高可读性。脱离async/await,Future本身的API仍然可以完成异步逻辑。

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

await必须在async{...} 中使用。
async{...}中使用await可以等待异步完成,但是不会阻塞线程。

await expression的expression通常是一个Future对象,如果不是则被自动包装成Future,这相对于Javascript更智能。

async的返回值会被自动包装成Future,例如在main函数使用async,会返回Future<Void>

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

lambda表达式中也可以出现async

Future<String> lookUpVersion() async => '1.0.0';

使用try...catch处理Future中的异常

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

Stream与async/await

熟悉RxJava的人都知道Stream的概念(流式数据),Dart中的Stream类型也有同样功能:连续多个数据的异步处理。

与Future一样,我们可以通过Stream的API或者通过async/await进行异步处理。
Stream使用类似循环语句的写法await for

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

await for 同样必须出现在 async{...}
像循环语句一样,通过return或者break可以结束stream处理

await for只能处理Cold Stream,即Stream中的数据是有始有终的,对于像Event监听这种没有固定数量的数据(Hot Stream)处理,无法使用,因为没有从循环外部取消订阅的API。
使用StreamAPI中的listene()可以得到StreamSubscription对象用来处理Hot Stream,它具有cancel方法可以取消订阅。


Generators(生成器)


JavaScript中有类似概念:用来生成Iterable 或者 Stream 的函数。

Stream相当于异步版本的Iterable

  • 同步生成器:返回Iterable对象
// body前需要加 sync* 
Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  // yield的地方,暂停执行并通过Itertable返回当前值k
  while (k < n) yield k++;
}
  • 异步生成器:返回Stream对象
    用法没有区别,只是sync* 换成 async*,比Javascrip异步生成器方便得多
Stream<int> asynchronousNaturalsTo(int n) async* {
  int k = 0;
  while (k < n) yield k++;
}

可以通过yield*提高尾递归的性能:

Iterable<int> naturalsDownFrom(int n) sync* {
  if (n > 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}

并发(Isolate)


Dart没有Thread,所有代码运行在Isolate上。
Dart通过启动多Isolate实现并发编程。

Isolate相对于Thread的主要不同在于,Isolate拥有独立的heap,互相之间不共享资源,隔离程度更接近进程。Isolate间通信需要通过开Port,类似socket方式的IPC。

import "dart:isolate";
import "dart:async";

void w(sendPort) {
    for(int i = 0; i< 100000; i ++) {
      print("waiting: $i");
    }
    sendPort.send("finished!");
}

main() async {
  final receivePort = ReceivePort();
  final sendPort = receivePort.sendPort;
  await Isolate.spawn(w, sendPort);
  receivePort.listen((msg){
    print("message from another Isolate: $msg");
  });
}

这种IPC式的通信不像线程间通信那样方便,但是安全性更高。

通过Isolate.spawnUri() 可以将main()中的其他文件在新的Isolate中执行,Flutter的主进程也是以这种方式启动的。



返回首页:Dart入门教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fundroid

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值