【问题标题】:Calling observable inside an error callback in Angular with RxJs使用 RxJs 在 Angular 的错误回调中调用 observable
【发布时间】:2022-01-23 17:15:28
【问题描述】:

我有两个相互依赖的 observable 调用,这工作正常,但是一旦响应中发生错误,我需要调用另一个 observable 来回滚事务。

Z这是我的代码:

return this.myService.createOrder()
    .pipe(
        concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID))  
    ).subscribe({
          error: (error: any): void => // TODO: Call another observable here passing res.orderId to rollback transaction
    });

正如您在 TODO 中看到的,我的计划是在 res.orderId 发生错误时调用另一个服务,但我不喜欢嵌套订阅。

是否可以在不创建嵌套订阅的情况下做到这一点???

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    正如@Emilien 指出的那样,catchError 在这种情况下是你的朋友。

    catchError 需要一个函数作为参数,该函数本身需要一个 error 作为输入并返回一个 Observable

    所以,代码可能是这样的

    // define a variable to hold the orderId in case an error occurs
    let orderId: any
    
    return this.myService.createOrder().pipe(
      tap((res: MyResponse) => orderId = res.orderId),
      concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID)), 
      catchError((error: any) => {
        // this.rollBack is the function that creates the Observable that rolls back the transaction - I assume that this Observable will need orderId and mybe the error to be constructed
        // catchError returns such Observable which will be executed if an error ouucrs
        return this.rollBack(orderId, error)
      })
    ).subscribe(console.log);
    

    如您所见,在这种情况下,整个 Observable 链只有一个订阅。

    【讨论】:

      【解决方案2】:

      不知道是否会解决,但您可以尝试使用CathError 吗?

      return this.myService.createOrder().pipe(
        concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID)), 
        catchError((res: MyResponse) => {
          // Call here your observable with res
        })
      ).subscribe(console.log);
      

      【讨论】:

      • 是的,我有这个,但此时 observable 仍然是 open,我宁愿不向它添加另一个订阅。我认为最好的方法是使用catchError 捕获错误,然后使用map 进行管道处理,然后调用订阅...类似的东西...
      【解决方案3】:

      捕捉和释放

      如果您仍然希望源 observable 出错。您可以捕获错误,运行您的回滚 observable,然后在完成后重新抛出错误。

      可能看起来像这样:

      this.myService.createOrder().pipe(
        concatMap((res: MyResponse) => this.addProduct(res.orderId, PRODUCT_ID).pipe(
          catchError(err => concat(
            this.rollBack(res.orderId),
            throwError(() => err)
          )
        )  
      ).subscribe(...);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-04
        • 1970-01-01
        • 2020-10-06
        • 1970-01-01
        • 2019-08-19
        • 1970-01-01
        • 1970-01-01
        • 2021-07-26
        相关资源
        最近更新 更多