-
Notifications
You must be signed in to change notification settings - Fork 213
await for ... and ... syntax #1440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Combined with syntax proposed by #1441 Stream<BBQStatus> deviceStatus() async* {
var status = BBQStatus.initial();
/// Temperature probe events and battery voltage events
await for (var e in service.probeEvents()) {
status = status.copyWith(probes: e);
yield status;
} and (var e in service.batteryEvents()) {
status = status.copyWith(battery: e);
yield status;
} on StreamException {
///
} catch(e) {
///
}
print('This is reachable when probeEvents and batteryEvents subscriptions complete '
'or either error handling block breaks');
} |
What you're asking for is a non blocking The big question is: When do you stop looping? Can you break it from the outside, or does it keep running until the stream ends (or the code inside the loop breaks out). What happens if your code inside the loop contains a The code must keep running event if the main control flow reaches the end of the function. What if it reaches that by throwing? That would normally emit an error on the stream and close it, but now it can't close it any more. (That could be a way to have streams with embedded errors, if the loops can also emit errors and events later). Basically, a way to do something in reaction to events, while staying inside the scope where you can still It's not clear how to makes consistent semantics for something like this. |
When I first posted this issue it was fairly broad, but I honed via edits it to a syntax which I believe handles the majority of the concerns raised.
The currently proposed syntax is still blocking, but it uses the
The proposed syntax "unblocks" when the
Can't return a value from a generator function (using the 'async*' modifier). How this works in a regular
The currently proposed syntax is blocking.
Please feel free to let me know if anything is still not handled. |
The change makes it two (or more) parallel loops. I wouldn't just allow it in a generator function, it should work in plain There are multiple ways to exit a loop:
Breaking the loop itself or completing normally are fine cases to just wait for the other loop. Control has only left one of the loops, and wants to continue right after the loop. We can wait for the other loop(s) and see if they get there too. In all the other cases, it should probably break both/all loops when control flow exits the combined If you combine it with #1441 (and even #171), I'd probably want individual exception handlers on each loop, so: await for (var e in stream) {
doSomething(e);
} catch (e) {
doSomethingElse(e);
} else {
doSomethingAtTheEnd();
}
and for (var e in otherStream) {
doWhatNot(e);
} catch (e) {
doWhatNotElse(e);
} else {
doWhatNotAtTheEnd();
} so the grammar would be: <asyncLoop> ::= `await` <forInLoop> (`and` <forInLoop>)* where it's a compile-time error if the expression of the The We'd probably have to make |
Looks good to me! Is there anything left to figure out? |
I'm not aware of any way to subscribe to two streams using
await for
in anasync*
block. There are stream combining tools made available inrx_dart
but I believe there is a lot of benefit to making this available with the core async tools.As it stands today, I am not aware of any way to combine these two streams in an
async*
block.You can combine streams using solutions like rx_dart's
CombineLatestStream.combine2
, but having syntax to allow us to handle this would be really nice.Here is a concept that is similar to syntax proposed by #1441
The text was updated successfully, but these errors were encountered: