mergeMap取消以前的HTTP调用

问题描述 投票:1回答:1

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

angular rxjs observable ngrx ngrx-effects
1个回答
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;
    })
    ))
  );
© www.soinside.com 2019 - 2024. All rights reserved.