dart异步
在 Dart 2 中,异步编程是一个核心特性,它使得处理耗时操作(如网络请求、文件 I/O、数据库操作等)变得更加高效和简洁。Dart 提供了几种机制来支持异步编程,包括 Future、async/await 和 Stream。
1. Future
Future 是 Dart 中表示异步操作结果的对象。一个 Future 对象代表一个可能还未完成的操作,它最终会产生一个结果值或一个错误。
- 创建和使用 Future
1 | Future<String> fetchUserOrder() { |
在这个例子中,fetchUserOrder 函数返回一个 Future,它模拟了一个耗时 2 秒的操作。通过 then 方法可以处理 Future 完成后的结果,通过 catchError 方法可以捕获可能发生的错误。
2. async/await
async 和 await 是 Dart 中用于简化异步代码编写的语法糖。使用 async 关键字标记的函数会返回一个 Future,而 await 关键字可以暂停函数的执行,直到 Future 完成。
- 使用 async/await
1 | Future<String> fetchUserOrder() async { |
在这个例子中,fetchUserOrder 函数被标记为 async,并使用 await 关键字等待 Future 完成。main 函数也被标记为 async,并使用 await 关键字等待 fetchUserOrder 的结果。这种方式使得异步代码看起来更像同步代码,更易于理解和维护。
3. Stream
Stream 是 Dart 中用于表示异步数据序列的对象。一个 Stream 可以产生多个值(事件),这些值可以是数据或错误,最终可以完成或永远不完成。
- 创建和使用 Stream
1 | Stream<int> countStream(int to) async* { |
在这个例子中,countStream 函数返回一个 Stream,它每隔一秒产生一个数字。通过 listen 方法可以监听 Stream 的事件,处理数据、错误和完成事件。
4. 错误处理
在异步编程中,错误处理非常重要。Future 和 Stream 都提供了错误处理机制。
- Future 的错误处理
1 | Future<String> fetchUserOrder() { |
yield 关键字
在 Dart 中,yield 关键字用于生成一个值并将其发送给 Stream 的订阅者。使用 yield 可以创建一个异步生成器函数,这样的函数会返回一个 Stream,可以逐步产生多个值,而不是一次性返回一个结果。
异步生成器函数
异步生成器函数使用 async* 关键字来定义,并且可以使用 yield 关键字来逐步生成值。这些值会被发送到 Stream 的订阅者。yield 的作用
当使用 yield 时,函数会暂停执行并发送一个值给订阅者。下一次当订阅者请求下一个值时,函数会从上次暂停的地方继续执行。async* 和 yield 的示例
以下是一个具体示例:
1 | Stream<int> countStream(int to) async* { |
定义 countStream 异步生成器函数:
使用 async* 关键字定义这个函数。
使用 yield 关键字逐步生成值。生成值并发送给订阅者:
在循环中,每隔一秒生成一个值并使用 yield 将其发送给订阅者。
在主函数中订阅 Stream 并处理值:使用 await for 循环来订阅 Stream 并处理生成的每个值。
- yield* 关键字
除了 yield,Dart 还提供了 yield* 关键字,它用于将另一个生成器的输出直接传递给当前生成器的订阅者。以下是一个简单示例:
1 | Stream<int> numbers() async* { |
代码解释:
定义 numbers 异步生成器函数:
使用 yield 生成几个整数值。定义 moreNumbers 异步生成器函数:
使用 yield* 将 numbers 生成的所有值传递给当前生成器。
生成额外的值。在主函数中订阅 Stream 并处理值:
使用 await for 循环来订阅 Stream 并处理生成的每个值。