问题
I am trying to create a BLOC which depends on two other time based bloc and a non-time based bloc. What i mean with time based is, for example they are connecting a remote server so it takes time. It's working just like this:
Login (It's of course taking some time)
If login is successful
Do another process (This is something takes time also. It returns a future.)
After login and another process finishes, let the page know it.
My BLOC depends on these three:
final UserBloc _userBloc;
final AnotherBloc _anotherBloc;
final FinishBloc _finishBloc;
Inside the map event to state method I should dispatch relevant events. However i cannot await if they are finished.
_userBloc.dispatch(
Login(),
);
_anotherBloc.dispatch(
AnotherProcess(),
);
//LetThePageKnowIt should work after login and another process
_finishBloc.dispatch(
LetThePageKnowIt(),
);
Is there a clean way to await some others before dispatching something?
Right know I use a way that i don't like. In the main bloc's state which i connect other blocs in it, I have bools.
class CombinerState {
bool isLoginFinished = false;
bool isAnotherProcessFinished = false;
I am listening the time dependent blocs' states in constructor of main bloc. When they yield "i am finished" I just mark the bools "true".
MainBloc(
this._userBloc,
this._anotherBloc,
this._pageBloc,
); {
_userBloc.state.listen(
(state) {
if (state.status == Status.finished) {
dispatch(FinishLogin());
}
},
);
_anotherBloc.state.listen(
(state) {
if (state.status == AnotherStatus.finished) {
dispatch(FinishAnotherProcess());
}
},
);
}
and I dispatch another event for main bloc to check if all the bools are true after setting a bool to true.
else if (event is FinishAnotherProcess) {
newState.isAnotherProcessFinished = true;
yield newState;
dispatch(CheckIfReady());
}
If the bools are true, i dispatch LetThePageKnowIt()
else if (event is CheckIfReady) {
if (currentState.isAnotherProcessFinished == true &&
currentState.isLoginFinished == true) {
_pageBloc.dispatch(LetThePageKnowIt());
}
}
I am not satisfied with this code. I am looking a way to await other BLOCs send a state with "finished". After that I want to dispatch my LetThePageKnowIt()
回答1:
@pskink 's suggestion solved my problem.
I have created two methods which return a future. Inside of them, I just await for my streams. Here is the example of login stream.
In map event to state, after the dispatches, I await an async method.
_userBloc.dispatch(
Login(),
);
_anotherBloc.dispatch(
AnotherProcess(),
);
await loginProcess();
await otherProcess();
_finishBloc.dispatch(
LetThePageKnowIt(),
);
Inside the method I just await for userbloc to finish its job and yields about it. Then return.
Future loginProcess() async {
await for (var result in _userBloc.state) {
if (result.status == Status.finished) {
return;
}
}
}
来源:https://stackoverflow.com/questions/56322631/awaiting-some-results-before-dispatching-an-event-with-flutter-bloc-library