可以确定 epics 何时在 Redux Observable 中完成?

Possible to determine when epics finish in Redux Observable?

我是 RxJS 的新手,如果它没有多大意义,我深表歉意。

假设我想要一个可重复使用的史诗来获取用户,该用户将被应用加载史诗中的操作调用。

过度简化的示例:

const getUserEpic = action$ =>
  action$.pipe(
    ofType(GET_USER_REQUEST),
    switchMap(action => from(service.fetchUser(action.userId).pipe(
     mapTo({ type: GET_USER_SUCCESS })))
    ),
  );

const appLoadEpic = action$ => 
 action$.pipe(
    ofType(LOAD_APP_REQUEST),
    map(() => of({ type: GET_USER_REQUEST }, { type: SOME_OTHER_REQUEST }))
  );

如果我想在所有调用的 epics(getUser 等)完成后调用 LOAD_APP_SUCCESS 怎么办?如果能在appLoadEpic里做就好了,恐怕做不到。

我建议的方法是将个人 epics 组合成 "meta" 史诗。也就是说,您可以使用各个流来侦听它们各自的事件,并在所有合并流完成时传播它们。

const getUserEpic = action$ => ... 
const someOtherEpic = action$ => ...
// Creates an epic that merges all the results from each provided epic
const initializationEpic = combineEpics(getUserEpic, someOtherEpic)

const appLoadEpic = (action$, state$) => {
  // Runs the new epic with the action and state values.
  const onLoad$ = initializationEpic(action$, state$).pipe(
    endWith({type: LOAD_APP_SUCCESS})
  )

  // Listen for the load app request before subscribing to the initialization
  action$.pipe(
    ofType(LOAD_APP_REQUEST),
    mergeMapTo(onLoad$),
  )
}

如果你觉得很花哨,不想通过导入注入 epics,你也可以动态注入 epics docs 详细介绍了注入的方法异步史诗,这意味着您可以在启动期间将其作为动作主体的一部分而不是文件注入,这可能会使测试更容易一些。

  const appLoadEpic = (action$, state$) => {
    // Listen for the load app request before subscribing to the initialization
    action$.pipe(
      ofType(LOAD_APP_REQUEST),
      // Now the epic is injected during the app loading, and you run it inline 
      // here. This makes it easy to mock it during testing
      mergeMap(({epic}) => epic(action$, state$).pipe(endWith({type: LOAD_APP_SUCCESS}))),
    )
  }