Angular& RxJS - 使用.mergeMap组合多个XHR服务调用

时间:2017-10-26 13:40:15

标签: angular typescript rxjs

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

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

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中的两种服务方法都需要第一次服务调用的数据,如何向我的代码添加第三次服务调用?

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

2 个答案:

答案 0 :(得分:1)

我认为您可以链接多个mergeMap(或concatMap)个调用,并将结果映射到原始user个对象(我假设logSomething()返回a 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();

答案 1 :(得分:0)

您为什么使用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(...)