What does the yield
keyword actually do in Dart?
The accepted answer's link is broken, here is an official link about async* sync* yield* yield
.
If you have some experiences with other languages, you might stuck at these keywords. Here are some tips for getting over keywords.
async* sync* yield* yield
are called generator functions. You might use these mostly in Bloc pattern.
async*
is also a async
, you could use Asynchronous as usual.
sync*
cannot be used as sync
, you will receive the error that noticed "The modifier sync must be followed by a star".
yield
and yield*
can only be used with generator functions (async*
sync*
).
And there are four combinations.
async* yield
will return a 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*
will call a function and return Stream<dynamic>
.Stream<int> countDownFrom(int n) async* {
if (n > 0) {
yield n;
yield* countDownFrom(n - 1);
}
}
sync* yield
will return a Iterable<dynamic>
.Iterable<int> genIterates(int max) sync* {
var i = 0;
while (i < max) {
yield i;
i++;
}
}
sync* yield*
will call a function and return Iterable<dynamic>
.Iterable<int> countDownFrom(int n) sync* {
if (n > 0) {
yield n;
yield* countDownFrom(n - 1);
}
}
If there are any errors, please leave a comment to correct the answer.
yield
adds a value to the output stream of the surrounding async*
function. It's like return
, but doesn't terminate the function.
See https://dart.dev/guides/language/language-tour#generators
Stream asynchronousNaturalsTo(n) async* {
int k = 0;
while (k < n) yield k++;
}
When the yield statement executes, it adds the result of evaluating its expression to the stream. It doesn’t necessarily suspend (though in the current implementations it does).
The yield
statement can be used only in generator's functions.
The generator's function generates data items in natural way (as calculated, received from outside, predefined values etc).
When next data item is ready then the yield
statement send this item into data sequence which is essentially the generation result of the function.
The data sequence can be synchronous or asyncronous.
In Dart language the synchronous data sequence means the instance of Iterable
.
The asynchronous data sequence means the instance of Stream
.
P.S.
Generator functions can generate data items indefinitely until the function returns.
But unlike normal functions, the result (the data sequence) will be returned immediately after the function call and can be used immediately.
The end of the data sequence, in this case, can be reached only when generator function will be terminated (successfully or by failure).