Angular 重写嵌套订阅

Angular 重写嵌套订阅,angular,rxjs,angular-akita,Angular,Rxjs,Angular Akita,我的原始代码很难调试和维护,所以我正在重写我的代码 原始代码 this.userService.getLocationId(id).subscribe( (locationId) => { this.userService.getUserParams(locationId).subscribe( (params) => { // This API would store users to Akita Store thi

我的原始代码很难调试和维护,所以我正在重写我的代码

原始代码

this.userService.getLocationId(id).subscribe(
  (locationId) => {
    this.userService.getUserParams(locationId).subscribe(
       (params) => {
          // This API would store users to Akita Store
          this.userService.getUsers(params).subscribe()
          // Get data from Akita Store
          this.users$.subscribe(
             (users) => {
                this.users = [...users]
                this.userService.putSomeUserFirst().subscribe(
                  (data) => {
                    if (data === true) {
                       this.users.unshift(user)
                       this.users = [...new Map(this.users.map(agent => [user.id, user])).values()];
                    } 
                  }
                )
             }
          )
       }
    )
  }
)
因此,基本上,我调用了几个API,API的参数基于上一个API结果,除了上一个API调用。最后一个API调用是关于按特定顺序组织用户

重写代码

this.userService.getLocation(id).pipe(

// Don't know which RxJS operator I should be using
  flatMap((locationId) => {
    if (locationId) {
      return this.userService.getUserParams(locationId)
    }
  }),
  flatMap((params) => {
    return this.userService.getUser(params)
  }),
  flatMap(() => {
   return this.users$
  })
).subscribe(
  (users) => {
    this.users = users
  }
)

我在实现原始嵌套订阅的最后一部分时遇到问题。重写代码是正确的方法吗?我应该如何编写剩下的部分以及应该使用哪个RxJS操作符?

是的,您采取了正确的方法。您应该始终避免嵌套
订阅

这将是您正在寻找的实现:

this.userService.getLocationId(id).pipe(
    switchMap((locationId) => this.userService.getUserParams(locationId)),
    switchMap((params) => this.userService.getUsers(params)),
    switchMap(() => this.users$),
    tap((users) => this.users = [...users]),
    switchMap(() => this.userService.putSomeUserFirst()),
    tap((data) => {
      if (data === true) {
        this.users.unshift(user);
        this.users = [...new Map(this.users.map(agent => [user.id, user])).values()];
      }
    })
  ).subscribe();
当您只想在管道内部执行某些操作(如赋值)时,请使用
tap
操作符

您在问题中使用的
flatMap
运算符与
switchMap
运算符略有不同。在这个特定的示例中,两者都可以很好地工作,但通常您将主要使用
switchMap
操作符


看看这个博客,了解不同的映射操作符在RxJS中是如何工作的:

我会使用
try
catch
async
函数以及
wait
调用数据。它将所有内容保持在同一缩进行上,而无需回调链接。