Dart中的async和async *有什么区别?

Jag*_*ngh 26 dart flutter

I am making an application using flutter framework . During this I came across with the keywords in Dart "async" and "async*". Can anybody tell me what's the difference between them? Thanks in advance.

Sur*_*gch 158

简答

  • async 给你一个 Future
  • async*给你一个Stream

异步

您将async关键字添加到执行一些可能需要很长时间的工作的函数。它返回包装在 a 中的结果Future

Future<int> doSomeLongTask() async {
  await Future.delayed(const Duration(seconds: 1));
  return 42;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过等待 Future 来获得该结果:

main() async {
  int result = await doSomeLongTask();
  print(result); // prints '42' after waiting 1 second
}
Run Code Online (Sandbox Code Playgroud)

异步*

您添加async*关键字以创建一个函数,该函数一次返回一堆未来值。结果被包装在一个流中。

Stream<int> countForOneMinute() async* {
  for (int i = 1; i <= 60; i++) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}
Run Code Online (Sandbox Code Playgroud)

技术术语是异步生成器功能。您使用yield返回值而不是return因为您没有离开函数。

您可以使用await for等待 Stream 发出的每个值。

main() async {
  await for (int i in countForOneMinute()) {
    print(i); // prints 1 to 60, one integer per second
  }
}
Run Code Online (Sandbox Code Playgroud)

继续

观看这些视频以了解更多信息,尤其是关于 Generators 的视频:

  • 如此完美的解释。我印象深刻 (6认同)
  • “观看这些视频”——如果您也能提供*文本*参考资料,那就太好了。不是每个人都喜欢视频... (3认同)
  • @kent2508,Dart 不会让你从 `async*` 函数返回值。你只能产生一个值。但是,您可以调用“return;”(不带值)提前退出该函数。 (3认同)
  • 如果 func with async* 不产生但返回一个值,会发生什么? (2认同)

Rém*_*let 32

Marking a function as async or async* allows it to use async/await keyword to use a Future.

两者之间的区别在于,async*它将始终返回a Stream并提供一些语法糖以通过yield关键字发出值。

因此,我们可以执行以下操作:

Stream<int> foo() async* {
  for (int i = 0; i < 42; i++) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}
Run Code Online (Sandbox Code Playgroud)

该函数每秒发出一个值,每次都会递增

  • 通过将函数标记为async*,我们可以使用yield关键字并返回数据流。 (7认同)

Sta*_*kin 21

解决方案、起源和见解

\n

这个答案包括简化且易于理解的示例

\n

async

\n

异步计算无法在启动时立即提供结果,因为程序可能需要等待外部响应,例如:

\n
    \n
  • 读取文件
  • \n
  • 查询数据库
  • \n
  • 从 API 获取数据
  • \n
\n

异步计算不会阻塞所有计算直到结果可用,而是立即返回一个 Future 对象,该对象最终将“完成”结果。

\n

示例(这种类型的异步调用只能在不返回响应的情况下使用):

\n
void main() async {\n  // The next line awaits 5 seconds\n  await Future.delayed(Duration(seconds: 5));\n  // Pseudo API call that takes some time\n  await fetchStocks();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Future

\n
\n

Future 表示不会立即完成的计算。普通函数返回结果,而异步函数返回 Future,\n最终将包含结果。当结果准备好时,未来会告诉你。

\n
\n
    \n
  • 当异步函数返回值时附加 Future
  • \n
  • 表示单个计算的结果(与 相比Stream
  • \n
\n

例子:

\n
Future<String> fetchUserOrder() =>\n    // Imagine that this function is more complex and slow.\n  Future.delayed(\n    const Duration(seconds: 2),\n        () => \'Large Latte\',\n  );\n\nvoid main(List<String> arguments) async {\n  var order = await fetchUserOrder(); \n  // App awaits 2 seconds\n  print(\'Your $order is ready\');\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Stream

\n

异步数据事件源。\n流提供了一种接收事件序列的方法。每个事件都是数据事件,也称为流的元素。

\n
    \n
  • 流是结果序列
  • \n
  • 从流中,您会收到结果通知(流元素)
  • \n
\n

async* (流)

\n

async*是一个返回 Stream 对象的异步生成器。专为创建流而设计。

\n

使用流和 async* 的示例:

\n
// Creating a new stream with async*\n// Each iteration, this stream yields a number\nStream<int> createNumberStream(int number) async* {\n  for (int i = 1; i <= number; i++) {\n    yield i;\n  }\n}\n\nvoid main(List<String> arguments) {\n  // Calling the stream generation\n  var stream = createNumberStream(5);\n  // Listening to Stream yielding each number\n  stream.listen((s) => print(s));\n}\n
Run Code Online (Sandbox Code Playgroud)\n

结果:

\n
1\n2\n3\n4\n5\n
Run Code Online (Sandbox Code Playgroud)\n

奖励:改造现有流

\n

如果您已有流,则可以根据原始流\xe2\x80\x99s 事件将其转换为新流。

\n

示例(与之前的代码相同但有所不同):

\n
Stream<int> createNumberStream(int number) async* {\n  for (int i = 1; i <= number; i++) {\n    yield i;\n  }\n}\n\n// This part is taking a previous stream through itself and outputs updated values\n// This code multiplies each number from the stream\nStream<int> createNumberDoubling(Stream<int> chunk) async* {\n  await for (final number in chunk) {\n    yield number*2;\n  }\n}\n\nvoid main(List<String> arguments) {\n  // Here we are Transforming the first stream through createNumberDoubling stream generator\n  var stream = createNumberDoubling(createNumberStream(5));\n  stream.listen((s) => print(s));\n}\n
Run Code Online (Sandbox Code Playgroud)\n

结果:

\n
2\n4\n6\n8\n10\n
Run Code Online (Sandbox Code Playgroud)\n

解决方案

\n

asyncasync*近亲,它们甚至来自同一个库dart:async\nasync代表 aFuture和 一次性交换,而async*代表 a Stream,多个事件的流

\n