【问题标题】:mergeMap cancels previous HTTP callsmergeMap 取消之前的 HTTP 调用
【发布时间】:2017-12-21 12:13:25
【问题描述】:

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

即使我使用的是mergeMap,为什么 XHR 被取消了?

【问题讨论】:

  • 能否添加处理LoadRefDataForId Action的效果代码?这个不负责发送任何类型的请求
  • 添加了代码@Jota.Toledo!我尝试将 switchMap 更改为 mergeMap 以使其一切正常,但我不明白为什么。是否没有合并三个单独的可观察对象,并且在其中任何一个中使用 switchMap 只会对该特定流产生影响?
  • 为什么关闭标志?是的,这是一个Why doesn't this code work? 类型的问题,但我认为它应该如何工作以及为什么工作,以及最后的推理问题有很大的不同。
  • 我个人标记了缺失效果的原因

标签: angular rxjs observable ngrx ngrx-effects


【解决方案1】:

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

@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 操作应该被考虑/处理。

改成:

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

【讨论】:

  • 有点明白为什么,但我仍然不明白为什么switchMap 不起作用。是否可以在合并到mergeMap 的任何其他可观察流中使用switchMap
猜你喜欢
  • 1970-01-01
  • 2016-06-16
  • 2013-08-03
  • 1970-01-01
  • 2019-11-26
  • 2020-12-28
  • 2023-04-01
  • 1970-01-01
  • 2021-04-03
相关资源
最近更新 更多