首页 > 解决方案 > 在 Observable 中调用 Promise

问题描述

我必须Promise在另一个 API 调用(returns)之后进行 API 调用(returns Observable)。

userService.getAuthUser()返回Observable一个.

userService.updateUser()返回Promise一个。

我可以通过把updateUser()里面getAuthUser()

this.userService.getAuthUser().subscribe((res) =>{
  this.userService.updateUser(res.id, <User>({
    name: 'Sample Name'
  })).then((res) =>{
    console.log('update user success');
  }).catch((err) => {
    console.log('update user failed');
  })
},
(err) => {
  console.log('get auth user failed');
})

但我觉得这样做不太好,有点回调地狱,还有更好的方法吗?

注意:我无法更改userService.updateUser()Observable.

标签: angularrxjses6-promise

解决方案


有几种方法可以实现这一目标。

如果您希望 getAuthUser 流保持活动状态,一种方法是使用from 运算符将 promise 转换为 observable 。这将允许您继续流并对整个流的错误/处理成功做出反应。您还可以使用catchError 运算符指定流中对特定错误做出反应的位置。

类似于:

this.userService.getAuthUser()
  .pipe(
    catchError(err => {
      // throw an error how you like, see the 'throw' operator
      // can also create with other operators like 'of'
    }),
    switchMap(auth =>
      from( // will detect promise and return observable
        this.userService.updateUser(res.id, <User>({
          name: 'Sample Name'
        }))
      )
    ),
    catchError(err => {
      // throw an error how you like, see the 'throw' operator
      // can also create with other operators like 'of'
    })

  ).subscribe(
    (res) => {
      // if you were expecting data at this point
    }, (err) => {
      // if you threw the error
    }
  )

另一种方法是,如果您不需要流保持活动状态,您可以将 Observable 从第一个流转换为带有.toPromise(). 从这里开始,您有两条典型的路径可供遵循。您可以使用async/await,或者只是链接承诺。

对于异步等待,类似于:

// the method will have to be async for await to not show errors

const authUser = await this.userService.getAuthUser().toPromise();

// determine if you should update
// if so

const updateUserResult = await this.userService.updateUser(res.id, <User>({name: 'Sample Name'}));

推荐阅读