具有redux-observable的动作序列

时间:2017-08-16 08:24:14

标签: redux redux-saga side-effects redux-observable

以下是我要实现的流程:所有用户的列表都在我的后端API上公开,所以我希望看看用户是否已经存在,如果没有,请创建一个新用户。

我正在使用Redux,我正在用redux-observable管理副作用。以下是我正在发送的相关操作的流程。

  • 按钮点击会调度操作FIND_OR_CREATE_USER。副作用应该处理下一步。
  • 在API后端查找用户 - 使用userId参数调度GET_USER_BY_ID_REQUEST,副作用将执行HTTP调用。
  • 接收用户 - 调度GET_USER_BY_ID_SUCCESS,响应存储在州。
  • 如果此响应为空,则使用CREATE_USER_REQUEST创建用户。

现在唯一的事情就是此GET_USER_BY_ID_SUCCESS也会在应用中的其他位置使用(例如,获取用户个人资料)。因此,如果响应为空,我无法收听GET_USER_BY_ID_SUCCESS并在其后创建用户。如果我们的GET_USER_BY_ID_SUCCESS位于FIND_OR_CREATE_USER之后,则只创建用户。

以下是我将如何使用redux-sagas:

function* findOrCreateUserSaga() {
  yield put({ type: 'GET_USER_BY_ID_REQUEST', payload: userId });
  yield take('GET_USER_BY_ID_SUCCESS');
  const response = yield select((state) => state.user);
  if (!response) {
    yield put({ type: 'CREATE_USER' }, payload: someObject );
  }
}

...

yield takeLatest('FIND_OR_CREATE_USER', findOrCreateUserSaga)

如何使用redux-observable以反应方式实现相同的流程?

1 个答案:

答案 0 :(得分:0)

您可以在史诗级的任何时间创建action$流的新订阅。这样,您可以动态地启动/停止侦听特定操作,以响应其他操作,工作流等。

这是将示例传奇转换为RxJS 6(使用管道)和redux-observable 1+(使用state$流)的例子。它使用merge函数创建一个可观察对象,该对象同时发出“ GET_USER_BY_ID_REQUEST”和侦听“ GET_USER_BY_ID_SUCCESS”。此外,内部first流管道中使用的action$运算符会在您执行匹配操作时使它完成。

const epic = (action$, state$) => action$.pipe(
  ofType('FIND_OR_CREATE_USER'),
  switchMap(action =>
    merge(
      of({ type: 'GET_USER_BY_ID_REQUEST', payload: userId }),
      action$.pipe(
        ofType('GET_USER_BY_ID_SUCCESS'),
        first(),
        withLatestFrom(state$),
        mergeMap(([action, state]) =>
          state.user
            ? empty()
            : of({ type: 'CREATE_USER', payload: someObject })
        ),
      ),
    )
  ),
)

示例传奇没有指定如何创建userIdsomeObject变量。注意,上述示例史诗也是如此。但是,根据您的特定用例来填补这些空白应该足够容易。