当前位置: 代码迷 >> 综合 >> Dart —— 异步支持
  详细解决方案

Dart —— 异步支持

热度:41   发布时间:2023-12-10 22:05:28.0

Dart汇总请点击这里

异步支持

Dart 库中包含许多返回 FutureStream 对象的函数. 这些函数在设置完耗时任务(例如 I/O )后, 就立即返回了,不会等待耗任务完成。 使用 asyncawait关键字实现异步编程。 可以让你像编写同步代码一样实现异步操作。

处理 Future

可以通过下面两种方式,获得 Future 执行完成的结果:

  • 使用 async 和 await.
  • 使用 Future API,具体描述,参考 库概览.

使用 asyncawait关键字的代码是异步的。 虽然看起来有点像同步代码。 例如,下面的代码使用 await 等待异步函数的执行结果。

await lookUpVersion();

要使用 await , 代码必须在 异步函数(使用 async 标记的函数)中:

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

提示: 虽然异步函数可能会执行耗时的操作, 但它不会等待这些操作。 相反,异步函数只有在遇到第一个 await 表达式(详情见)时才会执行。 也就是说,它返回一个 Future 对象, 仅在await表达式完成后才恢复执行。

使用trycatch, 和finally来处理代码中使用 await 导致的错误。

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 对象指明返回一个对象的承诺(promise)。 await 表达式 执行的结果为这个返回的对象。 await表达式会阻塞代码的执行,直到需要的对象返回为止。

如果在使用 await 导致编译时错误, 确认 await 是否在一个异步函数中。 例如,在应用的 main() 函数中使用 await , main() 函数的函数体必须被标记为 async :

Future main() async {
    checkVersion();print('In main: version is ${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

当需要从 Stream 中获取数据值时, 可以通过一下两种方式:

  • 使用 async 和 一个 异步循环 (await for)。
  • 使用 Stream API, 更多详情,参考 in the library tour。

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

以下是异步for循环的使用形式:

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

上面 表达式 返回的值必须是 Stream 类型。 执行流程如下:

  • 等待,直到流发出一个值。
  • 执行 for 循环体,将变量设置为该发出的值
  • 重复1和2,直到关闭流。

使用 break 或者return 语句可以停止接收 stream 的数据, 这样就跳出了 for 循环, 并且从 stream 上取消注册。 如果在实现异步 for 循环时遇到编译时错误, 请检查确保 await for 处于异步函数中。 例如,要在应用程序的 main() 函数中使用异步 for循环, main() 函数体必须标记为 async` :

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

有关异步编程的更多信息,请参考 dart:async 部分。 同时也可参考文章 Dart Language Asynchrony Support: Phase 1 和 Dart Language Asynchrony Support: Phase 2, 以及 Dart language specification 。