如何减少订阅运算符的数量并替换为其他rxjs运算符

问题描述 投票:0回答:2

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

//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)));
} 
angular rxjs angular2-observables
2个回答
-1
投票

尝试这样的事情:

this.login$ = this.loginServ.Login(userName, password).pipe(
  map(result => result.userData),
);

this.login$.pipe(
  filter(login => !login),
  tap(() => this.sessionService.increaseLoginAttempts()), // void method
);

this.login$.pipe(
  filter(Boolean),
  tap(() => this.sessionService.resetLoginAttempts()), // void method
  tap(() => this.router.navigateByUrl('')),
);

this.captcha$ = this.sessionService.loginAttempts$.pipe( // observable value
  filter(loginAttempts => loginAttempts >= 3),
  switchMap(() => this.loginServ.GetCaptcha()),
  // maybe setCaptchaImage() here since no idea what it does. maybe you can use async pipe for it?
);

-1
投票

如果您的RXJS调用不是真正应该链接的,那么我个人对多个.subscribe没有任何帮助。但是,如果您应该打两个电话,可以,您应该一起concatMap

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

如果您发出一个http请求,并且不希望打开流,那么您不必保留对任何RXJS调用的订阅。但是,如果您打算保持流打开,我建议您使用ngOnDestroy技术。您可以阅读有关它的更多信息"Don't forget to unsubscribe",也许您应该看一下相同的概念,但告诉您相反的情况:"Don't Unsubscribe":)

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

由于其他人已经对编码进行了评论,因此在这里我不会进行编码,但是您应该尝试一下!

© www.soinside.com 2019 - 2024. All rights reserved.