Redux-observable:在完成许多数据获取史诗后调用帮助程序函数



用户登录后,会进行多次 api 调用来加载用户数据。在这些calla完成后,用户将被重定向到其配置中指定的登录页面。

3 个 api 调用可以同时提取,但是,重定向必须等到获取完成。我已经在下面展示了我的尝试。

所有 api 调用都按预期工作,并将获取的数据存储在 Redux 中,因此(我认为(问题出在 loadUserEpic 上,它管理整个过程并调用重定向函数。我将如何更好地构建这部史诗以实现我想要的?

import { userRedirect } from 'ui/client/helpers/userRedirect';
const loadUserEpic = action$ =>
  action$.ofType('LOAD_USER').pipe(
    mergeMap(() =>
      Observable.of(
        {
          type: 'FETCH_USER_CONFIG'
        },
        {
          type: 'FETCH_USER_MODULES'
        },
        {
          type: 'FETCH_USER_DIVISION'
        },
        userRedirect()
      )
    )
  );
const userConfigEpic = action$ =>
  action$.ofType('FETCH_USER_CONFIG').mergeMap(() =>
    fromPromise(axios.get(`/me/configuration`))
      .map(response => ({
        type: 'FETCH_USER_CONFIG_SUCCESS',
        data: response.data
      }))
      .catch(error =>
        Observable.of({
          type: 'FETCH_USER_CONFIG_ERROR',
          error
        })
      )
  );
const userModulesEpic = action$ =>
  action$.ofType('FETCH_USER_MODULES').mergeMap(() =>
    fromPromise(axios.get(`/me/modules`))
      .map(response => ({
        type: 'FETCH_USER_MODULES_SUCCESS',
        data: response.data
      }))
      .catch(error =>
        Observable.of({
          type: 'FETCH_USER_MODULES_ERROR',
          error
        })
      )
  );
const userDivisionEpic = action$ =>
  action$.ofType('FETCH_USER_DIVISION').mergeMap(() =>
    fromPromise(axios.get(`/division/`))
      .map(response => ({
        type: 'FETCH_USER_DIVISION_SUCCESS',
        data: response.data
      }))
      .catch(error =>
        Observable.of({
          type: 'FETCH_USER_DIVISION_ERROR',
          error
        })
      )
  );

首先触发所有三个操作来获取数据:

const loadUserEpic = action$ =>
  action$.ofType('LOAD_USER').pipe(
    mergeMap(() =>
      Observable.of(
        {
          type: 'FETCH_USER_CONFIG'
        },
        {
          type: 'FETCH_USER_MODULES'
        },
        {
          type: 'FETCH_USER_DIVISION'
        },
      )
    )
  );

现在等待每个操作完成,并以某种方式检查您是否拥有所需的一切:

const redirectEpic = (action$, store) => 
  action$.ofType(
    'FETCH_USER_CONFIG_SUCCESS',
    'FETCH_USER_MODULES_SUCCESS',
    'FETCH_USER_DIVISION_SUCCESS'
  ).pipe(
    mergeMap(() => {
      const state = store.getState(); 
      const iHaveConfig = isConfigFetched(state);
      const iHaveModules = areModulesFetched(state);
      const iHaveDivisions = areDivisionsFetched(state);
      if(iHaveConfig && iHaveModules && iHaveDivisions) {
        return useRedirect();
      }
      return Observable.empty();
    })
  )

最新更新