< p > 在Dart中,< code > yield < /code > 关键字实际上是什么作用?< /p >
yield
将一个值添加到包围的 async*
函数的输出流中。它类似于 return
,但不会终止函数。
请参阅 https://dart.dev/guides/language/language-tour#generators
Stream asynchronousNaturalsTo(n) async* {
int k = 0;
while (k < n) yield k++;
}
当yield语句执行时,它会将其表达式的计算结果添加到流中。它不一定会挂起(尽管在当前的实现中它会挂起)。
async* sync* yield* yield
的官方链接。async* sync* yield* yield
被称为生成器函数。您可能会在Bloc模式中大量使用这些函数。
async*
也是一个 async
,您可以像往常一样使用异步。
sync*
不能像 sync
一样使用,否则您将收到错误提示"The modifier sync must be followed by a star"。
yield
和 yield*
只能与生成器函数(async*
sync*
)一起使用。
async* yield
将返回一个 Stream<dynamic>
。Stream<int> runToMax(int n) async* {
int i = 0;
while (i < n) {
yield i;
i++;
await Future.delayed(Duration(seconds: 300));
}
}
async* yield*
会调用一个函数并返回 Stream<dynamic>
。Stream<int> countDownFrom(int n) async* {
if (n > 0) {
yield n;
yield* countDownFrom(n - 1);
}
}
sync* yield
将返回一个 Iterable<dynamic>
。Iterable<int> genIterates(int max) sync* {
var i = 0;
while (i < max) {
yield i;
i++;
}
}
sync* yield*
会调用一个函数并返回 Iterable<dynamic>
。Iterable<int> countDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* countDownFrom(n - 1);
}
}
如有任何错误,请留下评论以更正答案。
我认为yield*的正确答案是将任务委派给另一个生成器而不是调用函数。yield*仅仅是将任务委派给另一个生成器,这意味着当前生成器停止执行,直到另一个生成器产生结果。在另一个生成器停止产生值之后,主生成器会恢复执行并继续产生自己的值。
感谢@András Szepesházi鼓励我将此评论作为答案发布,希望可以帮到您。
yield*
还有以下用途:A. 通过嵌套多个生成器来重构生成器代码 B. 递归生成器。 - om-hayield
语句只能在生成器函数中使用。yield
语句会将该项发送到数据序列中,这本质上是函数的生成结果。Iterable
实例。Stream
实例。
async*
函数中,yield
会暂停当前任务的执行,并将其切换到调用者(await for
循环)。如果不注意这一点,可能会导致非常奇怪的执行停顿。以下是一些示例来突出潜在的问题:非停顿示例,停顿示例 - undefined