仅当角度满足条件时如何执行 rxjs 转换运算符

ber*_*rno 6 observable rxjs angular

我想通过对服务器的 API 调用来验证优惠券代码,但首先我必须检查用户会话,因为我需要用户使用有效的会话令牌登录。如果会话已过期,我想显示登录对话框并完成流,可能无需输入订阅函数的下一个回调,如果会话仍然有效,我想调用 API 来验证优惠券并执行中的代码订阅函数的下一个回调。

applyCouponCode() {
  const user = this.auth.getUser();
  if (user) { //verify if user is logged in
    if (this.couponCode.length !== 0) {
      this.auth.checkSession() //API call to verify if user session is still valid
        .pipe(
          tap((sessionValid) => {
            if (!sessionValid) {
              //session expired
              this.auth.clientLogout();
              this.auth.showLoginDialog();
            } else {
              //session valid, call the API to validate the coupon code
              mergeMap(() => this.reservation.validateCouponCode(this.couponCode, user.token));
            }
          })
        )
        .subscribe(
          discountCode => {
            if (discountCode.valid) {
              //create the discount code obj and apply to user cart
              ....
            } else {
              //notify discount code is invalid to the user
              ....
            }
          },
          error => {
            console.log('error', error);
          }
        );
    } else {
      this.emptyCouponSubmitted = true;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

另一种可能的解决方案是重构管道函数中的运算符

.pipe(
  tap((sessionValid) => {
    if (!sessionValid) {
      this.auth.clientLogout();
      this.auth.showLoginDialog();
    }
  }),
  mergeMap((sessionValid) => {
    if (sessionValid) {
      return this.reservation.validateCouponCode(this.couponCode, user.token));
    } else {
      // I would like to complete the stream without enter in the next callback
      return of(null);
    }
  })
Run Code Online (Sandbox Code Playgroud)

仅当调用了验证优惠券代码的 API 时,我才想输入订阅下一个回调,并且如果用户会话已过期,我想完成流。这是对的吗?是否有更好的方法来根据先前的条件执行 mergeMap 运算符,并在不满足该条件时完成流?管理此类情况的最佳实践是什么?

ber*_*rno 3

我找到了解决我的问题的方法。我在 tap 和 mergeMap 运算符之间添加了一个过滤运算符

.pipe(
   tap((sessionValid) => {
     if (!sessionValid) {
       this.auth.clientLogout();
       this.auth.showLoginDialog();
     }),
     filter(sessionValid => sessionValid),
     mergeMap(() => this.reservation.validateCouponCode(this.couponCode, user.token))
)
Run Code Online (Sandbox Code Playgroud)

这样做,如果会话过期(sessionValid 为 false),我可以在不调用 mergeMap 运算符的情况下显示对话框,因为发出的值由过滤器运算符过滤,并且流完成而无需在订阅函数的下一个回调中输入,否则调用 mergeMap,我可以在 subscribe 函数中管理新流的结果。