mergeMap取消以前的HTTP调用

时间:2017-12-21 12:13:26

标签: angular rxjs observable ngrx ngrx-effects

我有一个对话框,当打开时会调度一个动作来为对话框中的表单控件预加载数据。该操作由一个效果拾取,该效果又返回一组新操作,以预加载传递给原始操作的数组中每个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"}

这取自网络日志

enter image description here

处理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

1 个答案:

答案 0 :(得分:3)

取消是由这种影响引起的:

@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,您告知只应考虑/处理通过LoadRefDataForId流的最后actions$操作。

将其更改为:

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