redux-observable - 等到请求完成后再开始另一个请求

redux-observable - wait until request finishes before starting another one

我的应用程序中有一个邀请列表,每个邀请都有相应的 删除 按钮。当用户单击 删除 时,将调度一个 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

我想我会问你为什么首先需要使用 redux-observable 来实现这一点。你不能在你的请求开始时在你的 redux 存储中设置一些状态变量(比如 deleteInProgress = true),并使用这个状态来禁用删除按钮。当您的请求完成时(成功或错误),将 deleteInProgress 标志设置回 false,这将 re-enable 按钮。

根据您在下面的评论,听起来您想要的是 exhaustMap

Projects each source value to an Observable which is merged in the output Observable only if the previous projected Observable has completed.

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,
            },
          },
        })),
      ),
    ),
  );