【问题标题】:Angular & RxJS - Combining Multiple XHR Service calls using .mergeMapAngular & RxJS - 使用 .mergeMap 组合多个 XHR 服务调用
【发布时间】:2018-04-07 22:21:52
【问题描述】:

我最近向prevent a pyramid of doom 提出了一个问题 并得到了很好的答案,但是随着我的系统的进步,我需要修改我的代码并且我的实现不起作用。

在我的系统中,我订阅了一个 Angular Material Dialog afterClose 操作,获取结果,过滤该结果,然后调用检索数据的服务(使用 REST / XHR)。解决此问题后,我将获取并修改一些返回的数据并返回另一个服务方法。 mergeMap用于防止一系列嵌套.subscribes

dialogRef
.afterClosed()
.filter((result) => typeof result === 'string')
.mergeMap((result) => this.myService.getuser(this.id).mergeMap((user: User) => {
  const mergedObj = Object.assign({}, user, {LifeEventDate: this.dateService.convertToCorrectFormat(result)});
  return this.myService.updateUser(this.id, mergedObj);
}))
.do(() => {
  // run some actions in the Component...
})
.subscribe();

现在我希望从 this.myService.getuser 获取一些返回的数据并调用相同的服务,但调用另一个方法 this.myService.logSomething(它也进行 REST / XHR 调用)。方法this.myService.logSomething 不返回任何必要的数据,完成后它只返回一个对象{success: true},尽管在出现错误时引入.catch 可能是谨慎的。我想将它添加到上面的代码中,将它放在第二个 mergeMap 中不起作用,因为在 Chrome 开发工具中查看时没有为此发出网络请求。比如……

dialogRef
.afterClosed()
.filter((result) => typeof result === 'string')
.mergeMap((result) => this.myService.getuser(this.id).mergeMap((user: User) => {

  /* NEW CODE */
  // I need to take some of the data returned from the returned user above
  this.myService.logSomething({user:user.id, something: user.something, somethingElse: user.somethingElse});

  const mergedObj = Object.assign({}, user, {LifeEventDate: this.dateService.convertToCorrectFormat(result)});
  return this.myService.updateUser(this.id, mergedObj);
}))
.do(() => {
  // run some actions in the Component...
})
.subscribe();

我不确定在哪里或如何拨打这个新的服务电话。嵌套在第一个 .mergeMap 中的两个服务方法都需要来自第一个服务调用的数据,如何将第三个服务调用添加到我的代码中?

抱歉,如果问题结构不正确、没有意义或不清楚,请告诉我,我会改写。

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    我认为您可以链接多个mergeMap(或concatMap)调用并将结果映射到原始user 对象(我假设logSomething() 返回一个Observable):

    dialogRef
      .afterClosed()
      .filter(...)
      .mergeMap((result) => this.myService.getuser(this.id))
      .mergeMap(user => this.myService
        .logSomething(...)
        .map(() => user)) // !!!
      )
      .mergeMap(user => this.myService.updateUser(...))
      .do(() => ...)
      .subscribe();
    

    【讨论】:

    【解决方案2】:

    您为什么使用mergeMap?我会尝试这样的事情:

    dialogRef.afterClosed().filter(...)
        .switchMap(e => this.mysService.getUser(this.id))
        .switchMap(user => Observable.forkJoin(
            this.myService.logSomething(user),
            (user) => {
                const mergedObj = Object.assign();
                return this.myService.updateUser(this.id, mergedObj)
            },
            (a,b) => b //Selector: return a to pass along the first observable's result
        ))
        .do(...)
        .subscribe(...)
    

    【讨论】:

    • 为什么在这里切换地图?切换地图不等待 Http 调用完成。
    猜你喜欢
    • 2018-12-07
    • 2019-01-31
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 2018-07-31
    • 2018-03-09
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多