mergeMap 取消之前的 HTTP 调用

mergeMap cancels previous HTTP calls

我有一个对话框,当它打开时会调度一个操作来为对话框内的表单控件预加载数据。该动作由一个效果拾取,该效果又 returns 一个新动作数组,用于为传递给原始动作的数组中的每个 id 预加载数据。

@Effect()
preloadReferenceData$ = this.actions$
  .ofType(PRELOAD_REFDATA)
  .pipe(
    map((action: PreloadRefData) => action.payload),
    mergeMap(ids => {
      const actions: Action[] = [];
      ids.forEach((id) => actions.push(new LoadRefDataForId(id)));
      return actions;
    })
  );

通常情况下,我使用 mergeMap 运算符从一个效果中成功调度多个新动作,尽管这是我第一次调度相同类型的多个动作,而且这是我第一次'我们经历过 XHR 调用被取消的情况。我会怀疑在 XHR 调用被取消的情况下使用 switchMap,但现在当我使用 mergeMap.

时不会

这些是actions

的内容
LoadRefDataForId {payload: "2441", type: "[Refdata] Load RefData"}
LoadRefDataForId {payload: "7612", type: "[Refdata] Load RefData"}
LoadRefDataForId {payload: "9411", type: "[Refdata] Load RefData"}

这取自网络日志

处理LoadRefDataForId动作的效果

@Effect()
loadRefDataForId$ = this.actions$
  .ofType(LOAD_REFDATA_FOR_ID)
  .pipe(
  map((action: LoadRefDataForId) => action.payload),
  switchMap((id) => this.service.loadRefData(id)
    .pipe(
    map((occupations) => {
      return new LoadRefDataForIdSuccessful({ id: id, occupations: occupations } as RefDataPayload);
    }),
    catchError((err, caught) => {
      console.log(caught);
      return caught;
    })
    ))
  );

为什么 XHR 被取消了,即使我正在使用 mergeMap

取消的原因是:

@Effect()
loadRefDataForId$ = this.actions$
  .ofType(LOAD_REFDATA_FOR_ID)
  .pipe(
  map((action: LoadRefDataForId) => action.payload),
  switchMap((id) => this.service.loadRefData(id)
    .pipe(
    map((occupations) => {
      return new LoadRefDataForIdSuccessful({ id: id, occupations: occupations } as RefDataPayload);
    }),
    catchError((err, caught) => {
      console.log(caught);
      return caught;
    })
    ))
  );

通过在其中使用 switchMap,您表示只有通过 actions$ 流的最后一个 LoadRefDataForId 操作应该是 considered/processed.

改为:

@Effect()
loadRefDataForId$ = this.actions$
  .ofType(LOAD_REFDATA_FOR_ID)
  .pipe(
  map((action: LoadRefDataForId) => action.payload),
  mergeMap((id) => this.service.loadRefData(id)
    .pipe(
    map((occupations) => {
      return new LoadRefDataForIdSuccessful({ id: id, occupations: occupations } as RefDataPayload);
    }),
    catchError((err, caught) => {
      console.log(caught);
      return caught;
    })
    ))
  );