redux-observable - 等到请求完成后再启动另一个

时间:2018-02-22 09:39:16

标签: javascript redux rxjs redux-observable

我的应用中有一个邀请列表,每个邀请都有相应的删除按钮。当用户点击删除时,会调度DELETE_INVITE操作并发生史诗般的攻击:

const deleteInvite = (action$: any, store: Store<ReduxState, *>) =>
  action$.pipe(
    ofType(DELETE_INVITE),
    mergeMap(({ payload }) =>
      ajax(api.deleteInvite(payload.inviteId)).pipe(
        map((response: Object) => ({
          type: DELETE_INVITE + SUCCESS,
          payload: {
            data: response.response,
            status: response.status,
          },
        })),
        catchError((error: Object) => of({
          type: DELETE_INVITE + FAILURE,
          error: {
            response: {
              data: error.xhr.response,
              status: error.xhr.status,
            },
          },
        })),
      ),
    ),
  );

现在我想确保当时只触发一个请求并等到最后一个请求完成。换句话说,我想保护自己免受用户快速点击所有按钮并同时发出少量请求的情况的保护。

switchMap是我正在寻找的东西,因为它只能处理最近的点击...但是请求已经被触发并且UI留下了过时的数据。所以我需要的东西只有在内链完成时再次调用mergeMap

2 个答案:

答案 0 :(得分:1)

我想我会问为什么你需要使用redux-observable来实现这一点。你不能只在你的请求开始时在redux商店中设置一些状态变量(如deleteInProgress = true),并使用此状态禁用删除按钮。当您的请求完成(成功或错误)时,将deleteInProgress标志设置为false,这将重新启用该按钮。

答案 1 :(得分:1)

根据您的评论,听起来像exhaustMap

  

将每个源值投影到Observable,该Observable仅在先前投影的Observable已完成时才合并到输出Observable中。

const deleteInvite = (action$: any, store: Store<ReduxState, *>) =>
  action$.pipe(
    ofType(DELETE_INVITE),
    exhaustMap(({ payload }) =>
      ajax(api.deleteInvite(payload.inviteId)).pipe(
        map((response: Object) => ({
          type: DELETE_INVITE + SUCCESS,
          payload: {
            data: response.response,
            status: response.status,
          },
        })),
        catchError((error: Object) => of({
          type: DELETE_INVITE + FAILURE,
          error: {
            response: {
              data: error.xhr.response,
              status: error.xhr.status,
            },
          },
        })),
      ),
    ),
  );