【问题标题】:A way to call a subscription for each value within the subscription value without callback hell一种为订阅值中的每个值调用订阅而无需回调地狱的方法
【发布时间】:2021-04-02 01:48:23
【问题描述】:

所以我目前有一个返回团队的订阅,团队内部有一个存储用户对象的数组。我想为这些用户中的每一个调用另一个订阅。 下面是团队对象的视图:

team: {
    teamName: 'blueberries',
    teamMembers: [{UserObject}, {UserObject}]
}

下面是 userObject:

user: {
    uid: 1,
    uname: 'DPR'
}

我目前有这段代码,我在其中为团队订阅 getRequest,然后点击团队 Observable 并获取用户数组,然后为每个我运行订阅。代码如下:

this.teamService.getTeam(id)
   .pipe(
       tap(team => {
          team.teamMembers.forEach((eachUser) => {this.userService.updateUser(eachUser).subscribe()})
       })
   )
   .subscribe()

虽然它有效,但我真的很想避免在订阅中进行订阅,我曾尝试使用 switchMap 执行此操作,但它似乎无法在 switchMap 运算符中运行代码。下面是我试过但没有用的代码:

this.teamService.getTeam(id)
   .pipe(
       tap(team => {
          team.teamMembers.forEach((eachUser) => 
          switchMap(() => {return this.userService.update(eachUser)})
       })
   )
   .subscribe()

【问题讨论】:

    标签: angular rxjs angular2-observables rxjs-observables


    【解决方案1】:

    试试下面的方法

        this.teamService
          .getTeam(id)
          .pipe(switchMap((team) => this.updateMembers(team)))
          .subscribe();
    
      private updateMembers(team: Team) {
        return forkJoin(
          team.teamMembers.map((member) => this.userService.update(eachUser))
        );
      }
    

    您的代码不起作用的原因是您从未订阅 userService.update()。

    【讨论】:

      【解决方案2】:

      您可以将team 数组映射到userService.updateUser 调用数组。 然后您可以使用forkJoin(calls)merge(...calls)concat(...calls) 订阅这些电话。

      根据您希望订阅呼叫的方式以及接收结果的方式,它们各自具有不同的行为。由于您没有从updateUser 获得结果,因此mergeforkJoin 可能没问题。

      看起来像这样:

      this.teamService.getTeam(id).pipe(
        map(team => team.teamMembers.map(user => 
          this.userService.updateUser(user)
        )),
        switchMap(serviceCalls => merge(...serviceCalls))
      ).subscribe();
      

      您可以像这样组合mapswitchMap

      this.teamService.getTeam(id).pipe(
        switchMap(team => merge(...
          team.teamMembers.map(user => 
            this.userService.updateUser(user)
          )
        ))
      ).subscribe();
      

      【讨论】: