Dart2基础--异步支持

Dart库中包含许多返回 FutureStream 对象的函数。这些函数是异步的:它们在启动一个耗时操作(例如I/O操作)后返回,而不是等待该耗时操作完成。

asyncawait 关键字支持异步编程,它们使你编写异步代码看起来跟编写同步代码一样。

处理Futures

当你需要一个已经完成了的Future对象的结果时,你有两个选择:

使用asyncawait 的代码是异步的,但是看起来像是同步代码。例如,这里的代码使用 await 来等待一个异步函数的结果:

await lookUpVersion();

要使用 await ,代码必须在一个异步函数内部—一个被标记为 async 的函数:

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

注意: 虽然异步函数可能执行耗时的操作,但它不会等待这些操作。相反,异步函数只在遇到第一个await表达式时执行( details )。然后它会返回一个Future对象,尽在 await 表达式完成之后才恢复执行。

在使用 await 的代码处通过 trycatchfinally 来处理错误以及清理工作。

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

你可以在一个异步函数里多多次使用 await 。例如:

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

await 表达式中,表达式的值通常是一个 Future ;如果不是,那么他的值会被自动的封装为一个 Future 对象。这个 Future 对象会保证返回一个对象。 await 表达式的值就是那个返回的对象。 await 表达式使得执行暂停,直到结果对象可用。

如果你在使用 await 时出现一个编译时错误,确保 await 是在一个异步函数中。例如,要在你的APP的 main() 函数中使用 await ,那么 main() 函数的函数体必须被标记为 async

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

声明异步函数

一个异步函数是一个函数体被标记为 async 的函数。
给一个函数添加 async 关键字使它返回一个 Future 。例如,考虑下面这个返回一个字符串的同步函数:

String lookUpVersion() => '1.0.0';

如果你将它改变成异步函数,那么它的返回值是一个 Future。

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

注意,函数的函数体不需要使用 Future API .Dart 会在需要的时候创建 Future 对象。
如果你的函数不需要返回一个有用的值,那么它的返回类型是 Future<void>

处理流(Streams)

当你需要从一个流(Stream)获取值时,你有两个选择:

  • 使用 async 和一个异步 for 循环( await for
  • 使用 Stream API,in the library tour

一个异步 for 循环的格式如下:

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

上面的代码中 expression 的类型必须是 Stream,执行过程如下:
1. 会一直等待直到流发射一个值
2. 使用发射的值作为变量,执行for循环的循环体
3. 重复 1 和 2 ,直到流被关闭

要停止对流的监听,你可以使用一个 breakreturn 语句,它可以终止 for 循环并且解除对流的订阅。

当实现一个异步的for循环时如果出现一个编译时错误,确保 await for 在一个异步函数中。例如,在你的APP的 main() 函数中使用一个异步 for 循环, main() 的函数体必须被标记为 async

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

关于异步编程的更多信息,请参考:dart:async.

生成器(Generators)

当你需要延迟产生一些数据序列时,使用生成器函数。Dart 支持两种生成器函数:

  • 同步生成器:返回一个Iterable 对象
  • 异步生成器:返回一个Stream 对象

要实现一个 同步 生成器函数,将函数体标记为 sync* ,并且使用yield 语句来发送数据。

Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}

要实现一个 异步 生成器函数,将函数体标记为 async* ,并且使用 yield 语句来发送数据。

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);
  }
}

可调用的类

要允许像函数一样调用Dart类的实例,实现 call() 方法即可:

class WannabeFunction {
  call(String a, String b, String c) => '$a $b $c!';
}

main() {
  var wf = new WannabeFunction();
  var out = wf("Hi","there,","gang");
  print('$out');
}

Isolates

大多数计算机,即使是在移动平台上,都拥有多核心CPU。要充分使用所有的这些核心,开发人员传统上使用共享内存的线程并发执行。然而,共享状态的并发执行容易出错,并且可能导致代码复杂化。

所有Dart代码都在 isolates 中运行,而不是线程。每一个 Isolate 都有它自己的内存堆,这就确保没有任何 Isolate 状态可以被其他任意 isolate 访问。

关于 Isolates 的更多信息, dart:isolate library documentation

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值