使用rxjs预防毁灭金字塔。使用Angular订阅 - 扁平化.subscribes

时间:2017-10-18 07:53:46

标签: angular typescript rxjs observable

我目前正在调查RxJS's .merge但是我也会在这里提出这个问题,因为我有时会在这里找到解释。

好吧,我有一个表单,根据用户输入打开一个模态窗口,我订阅模态关闭事件并传回一些数据,我将调用/订阅服务方法后检索一些数据,然后当发生这种情况时,我再次执行相同的操作并调用/订阅另一个服务方法来更新某个日期,然后当它完成时我运行本地方法。所以我在这里有3个嵌套的.subscribe s

const dialogRef = this.matDialog.open(ModalWindowComponent, {});
let userId = 4; // this is the real world is selected by the user
let userData = {}; // this is actually form data created by the user

// dialog is closed
dialogRef.afterClosed().subscribe((result) => {
  if (typeof result === 'string') {
     // subscribe to a service to get some data
     this.userService.getUser(userId).subscribe((user: any) => {
        // do something with the data
        let mergedObj = Object.assign({}, user, {newProperty: result});
          // subscribe to another service to update the data
          this.scbasService.updateUser(userId, mergedObj).subscribe(() => {
             this.doSomethingElse(userData); 
      });
    });
  }
});

我这里有一个“厄运金字塔”。我记得在使用AngularJS并使用promises时我可以返回下一个服务并链接.then()。我真的想要压扁我的代码,任何想法?

我怎么能在这里做同样的事情,所以我的代码不会经常缩进?

如果我没有这么好地问过或解释过,请说出来,我会重新解释我的问题。

1 个答案:

答案 0 :(得分:3)

你可以这样做:

filter
  • 使用string,以便仅处理mergeMap个结果。
  • 使用getUserupdateUsermergeMap来电构成内部可观察对象。
  • 再次使用do将内部observable合并到外部observable中。
  • 在用户更新后使用subscribe执行某些操作。
  • 并致电subscribe。否则,什么都不会发生。

需要注意的是,在subscribe次调用中嵌套mergeMap次调用是一种反模式。

如果需要,可以使用第一个dialogRef .afterClosed() .filter(result => typeof result === 'string') .mergeMap( result => this.userService.getUser(userId), (result, user) => Object.assign({}, user, { newProperty: result }) ) .mergeMap( userWithNewProperty => this.scbasService.updateUser(userId, userWithNewProperty) ) .do(() => this.doSomethingElse(userData)) .subscribe(); 中的结果选择器进一步展平它,以添加属性:

{{1}}