Flutter开发相关:async 和 async* 在 Dart 中有什么区别?

发布于 1周前 作者 itying888 来自 Flutter

Flutter开发相关:async 和 async* 在 Dart 中有什么区别?

在 Dart 中,asyncasync* 都是用于定义异步函数的关键字,但它们有一些显著区别,主要体现在返回类型和使用方式上。

1. 返回类型不同

  • async:用于定义返回 Future 的异步函数。async 函数在执行时会返回一个 Future 对象,表示将来的某个时间点会提供一个值。
  • async*:用于定义返回 Stream 的异步生成器函数。async* 函数在执行时会返回一个 Stream,可以多次产生值,而不是像 async 函数一样只产生一次值。

2. 使用关键字不同

  • await:在 async 函数中,可以使用 await 关键字等待异步操作完成,然后再继续执行后续代码。
  • yield 和 yield*:在 async* 函数中,使用 yield 关键字一次产生一个值,提供给监听此 Stream 的订阅者。yield* 用于将一个 Stream 中的所有值转发给订阅者。

示例对比

async 示例

async 函数一次性返回一个 Future,可以通过 await 等待其结果:

import 'dart:async';

Future<int> asyncExample() async {
  // 模拟一个异步操作,例如网络请求或延时任务
  await Future.delayed(Duration(seconds: 2));
  return 42;
}

void main() async {
  int result = await asyncExample();
  print('Result from asyncExample: $result');
}

在这个例子中,asyncExample 是一个异步函数,在 Future.delayed 延迟 2 秒后返回一个 int42

async* 示例

async* 函数可以使用 yield 产生多个值,并返回一个 Stream

import 'dart:async';

Stream<int> asyncStarExample() async* {
  for (int i = 0; i < 5; i++) {
    // 每次 yield 一个值
    yield i;
    // 模拟异步操作
    await Future.delayed(Duration(seconds: 1));
  }
}

void main() async {
  StreamSubscription<int> subscription = asyncStarExample().listen((value) {
    print('Received value: $value');
  });

  // 等待一段时间,确保所有值都输出
  await Future.delayed(Duration(seconds: 6));
  subscription.cancel(); // 取消订阅
}

在这个例子中,asyncStarExample 是一个异步生成器函数。它每次 yield 一个值,并返回一个 Stream。通过 await for 循环,我们可以逐个读取 Stream 中的每个值。不过为了简化,这里使用了 listen 方法来监听 Stream 并打印每个值。

3. 适用场景

  • 使用 async:当函数是异步的,并且只会返回一个结果(例如执行完某个异步操作后得到一个单一值)。
  • 使用 async*:当函数是异步的,并且需要返回多个结果(例如逐步生成一系列值,或监听事件流)。

总结

特性 async async*
返回类型 Future Stream
使用关键字 await yield, yield*
使用场景 异步返回单一值 异步生成多个值

async 适合一次性返回结果的异步操作。async* 适合返回一系列结果的异步生成器。


更多关于Flutter开发相关:async 和 async* 在 Dart 中有什么区别?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter开发相关:async 和 async* 在 Dart 中有什么区别?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter开发中,Dart语言提供了对异步编程的良好支持,其中asyncasync*是两个重要的关键字,用于处理异步操作。尽管它们名字相似,但在用途和行为上有显著的区别。

async 关键字

async关键字用于标记一个函数为异步函数。异步函数会返回一个Future对象,这个对象代表了异步操作最终的结果。使用async关键字,你可以在函数内部使用await关键字来等待另一个异步操作的完成,而不会阻塞当前线程的执行。

Future<int> fetchDataAsync() async {
    // 模拟一个耗时操作,例如网络请求
    await Future.delayed(Duration(seconds: 2));
    return 42; // 假设这是从服务器获取的数据
}

void main() async {
    int result = await fetchDataAsync();
    print(result); // 输出 42
}

在上面的例子中,fetchDataAsync是一个异步函数,它使用await来等待一个模拟的耗时操作(Future.delayed)。在main函数中,我们同样使用await来等待fetchDataAsync的完成,并打印结果。

async* 关键字

async*关键字用于标记一个函数为异步生成器函数。异步生成器函数会返回一个Stream<T>对象,这个对象可以动态地产生一系列的值,而不需要一次性将所有值加载到内存中。这对于处理大量数据或需要逐步处理数据的场景非常有用。

Stream<int> generateNumbersAsync() async* {
    for (int i = 0; i < 5; i++) {
        // 模拟一个耗时操作
        await Future.delayed(Duration(milliseconds: 500));
        yield i; // 逐步产生值
    }
}

void main() async {
    StreamSubscription<int> subscription = generateNumbersAsync().listen((number) {
        print(number); // 逐步打印 0 到 4
    });

    // 等待一段时间以确保所有值都被打印出来
    await Future.delayed(Duration(seconds: 3));

    // 取消订阅
    subscription.cancel();
}

在上面的例子中,generateNumbersAsync是一个异步生成器函数,它使用async*yield关键字来逐步产生值。这些值在调用listen方法时会被异步地处理。在main函数中,我们订阅了这个流,并打印每个产生的值。注意,这里使用了StreamSubscription来管理订阅,并在适当的时候取消订阅。

总结

  • async关键字用于标记一个异步函数,它返回一个Future对象,表示异步操作的结果。
  • async*关键字用于标记一个异步生成器函数,它返回一个Stream<T>对象,可以逐步产生一系列的值。

这两个关键字在Dart中提供了强大的异步编程能力,使得在Flutter开发中处理异步操作变得更加灵活和高效。通过合理使用它们,可以开发出响应迅速且性能良好的应用程序。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!