Flutter Redux:如何等待多个调度结果并在所有操作完成后调度一个操作

时间:2020-02-07 07:43:06

标签: flutter flutter-redux

应用启动时,我调度一个动作FetchLocalDataRequestAction并在中间件中拦截该动作并调度多个动作。我想在所有动作完成后调度FetchLocalDataCompleteAction动作。我期望调度函数将返回一个Future,我可以等待,并且当所有Future完成时,我可以调度完成的操作。 我正在使用redux_epics中间件来使用流执行副作用

中间件

fetchLocalData<State>(
  Store<State> store,
  action,
  NextDispatcher next
){
  if(action is FetchLocalDataRequestAction){
    final futureLanguage = store.dispatch(FetchPreferredLanguageRequestAction());
    print('futureLanguage : $futureLanguage '); // null
    store.dispatch(FetchLocalUserRequestAction());
    store.dispatch(FetchOnboardingStatusRequestAction());
  }

  next(action);
}

史诗

Stream fetchUserEpic(Stream actions, EpicStore<AppState> store) =>
    actions.whereType<FetchLocalUserRequestAction>()
    .debounceTime(Duration(seconds: 5))
    .switchMap((action) => _fetchUser());

  Stream _fetchUser() => 
    handleException<AuthResponse, FetchLocalUserResultAction, FetchLocalUserErrorAction>(
      api: () => _mergeUser(),
      onResult: (result) => FetchLocalUserResultAction(result),
      onError: (error) => FetchLocalUserErrorAction(error)
    );

  Future<AuthResponse> _mergeUser() async {
      final token = await SharedPreferenceService.getAccessToken();
      final user = await SharedPreferenceService.getUser();

      return AuthResponse(token: token, user: user);
  }

  Stream fetchPreferredLanguageEpic(Stream actions, EpicStore<AppState> store) =>
    actions.whereType<FetchPreferredLanguageRequestAction>()
    .switchMap((action) => _fetchPreferredLanguage());

  Stream _fetchPreferredLanguage() =>
    handleException<String, FetchPreferredLanguageResultAction, FetchPreferredLanguageErrorAction>(
      api: () => SharedPreferenceService.getLanguageCode(),
      onResult: (code) => FetchPreferredLanguageResultAction(code),
      onError: (error) => FetchPreferredLanguageErrorAction(error)
    );

   Stream fetchOnboardingStatusEpic(Stream actions, EpicStore<AppState> store) =>
    actions.whereType<FetchOnboardingStatusRequestAction>()
    .switchMap((action) => _fetchOnboardingStatus());

  Stream _fetchOnboardingStatus() =>
    handleException<OnboardingStatus, FetchOnboardingStatusResultAction, FetchOnboardingStatusErrorAction>(
      api: () => SharedPreferenceService.getOnboardingStatus(),
      onResult: (status) => FetchOnboardingStatusResultAction(status),
      onError: (error) => FetchOnboardingStatusErrorAction(error)
    );

1 个答案:

答案 0 :(得分:1)

我建议结合使用redux_thunk软件包和Future.wait

CallableThunkAction将允许您调度一个动作并等待它。
然后,结合Future.wait,可以确保所有操作均已完成:


class MyThunkAction1 implements CallableThunkAction<AppState> {
  @override call(Store<AppState> store) async => await asyncMethod();
}

class MyThunkAction1 implements CallableThunkAction<AppState> {
  @override call(Store<AppState> store) async => await otherAsyncMethod();
}


func fetchLocalStuff() async {  
  List<Future> list = await Future.wait(
    MyThunkAction1.call(),
    MyThunkAction2.call(), // these are futures
  );
  // do your thing
}