首页 > 解决方案 > 如何减少订阅运算符的数量并用不同的 rxjs 运算符替换

问题描述

尝试减少订阅数量并为下面提到的代码使用等效的flatMap\switchMap\do\tap rxjs运算符。它正在工作,但我知道这不是最好的方法。代码如下: 首先 - 有一个凭证检查(用户名和通行证): A. 如果它获取用户数据,它 resetLoginAttempts - 将登录尝试次数重置为 0 并路由到不同的路由。B. 如果不是 (A) - 它增加登录尝试次数 - 将登录尝试次数增加 1。服务在增加后取回登录次数。根据它检查-如果登录尝试> = 3,那么它会生成Captcha,它也返回可观察的。

//loginSrv.Login - return observable of userData (json)
//sessionService.resetLoginAttempts - return observable of void 
//sessionService.increaseLoginAttempts - return observable of any (json)
//loginSrv.GetCaptcha - return observable of any (svg image)

subscriptions : Subscription[] = [];
login()
{
  this.subscriptions.push(this.loginSrv.Login(userName, password).subscribe(result =>
  {
    if (result &&  result.userData)
    {
      this.sessionService.resetLoginAttempts().subscribe();
      this.router.navigateByUrl('');
    }
    else
    {
        this.subscriptions.push(this.sessionService.increaseLoginAttempts().subscribe(result => 
        {
          if (result.loginAttempts >= 3)
          {
            this.generateCaptcha();
          }
        }, error => 
          {
                throwError(error))
          }
      ));
    }
  }, (error => throwError(error))
));
}


generateCaptcha()
{
  this.subscriptions.push(this.loginSrv.GetCaptcha().subscribe(response => 
    {
      this.captcha = response;
      this.setCaptchaImage();
    },  
    error => throwError(error)));
} 

标签: angularrxjsangular2-observables

解决方案


.subscribe如果您的 RXJS 调用不应该被链接起来,我个人并不反对多重。但是,如果你应该打 2 个电话,是的,你应该concatMap一起打。

另一件可以清理代码的事情是知道流是否真正完成。在我看来,这是 RXJS 的一个缺陷,不知道您拨打的电话是 1 次,还是实际上是一个流。

如果您发出一个 http 请求并且不希望保持流打开,那么您不必保留对任何 RXJS 调用的订阅。但是,如果您打算保持流打开,我会推荐该ngOnDestroy技术。您可以阅读有关它的更多信息“不要忘记取消订阅”,也许您应该看看相同的概念,但告诉您相反的内容:“不要取消订阅” :)

此外,您应该阅读更多关于您的throwError. 从技术上讲,这些应该会冒泡。实际学习的最佳方法是自己编写代码,我建议您创建一个名为 login$() 的冷可观察对象,它可以完成您应该做的所有事情。只有在它上面调用 .subscribe() 才会返回一个完整的observable。

由于其他人已经评论过如何编码,我不会在这里编码,但你应该试一试!


推荐阅读