尝试减少 订阅者的数量,并使用等效的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)));
}
尝试这样的事情:
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?
);
如果您的RXJS调用不是真正应该链接的,那么我个人对多个.subscribe
没有任何帮助。但是,如果您应该打两个电话,可以,您应该一起concatMap
。
可以清理代码的另一件事是知道流是否真正完成。在我看来,这是RXJS的缺陷,不知道您拨打的电话是一次性的,还是实际上是流的。
如果您发出一个http请求,并且不希望打开流,那么您不必保留对任何RXJS调用的订阅。但是,如果您打算保持流打开,我建议您使用ngOnDestroy
技术。您可以阅读有关它的更多信息"Don't forget to unsubscribe",也许您应该看一下相同的概念,但告诉您相反的情况:"Don't Unsubscribe":)
此外,您还应该阅读有关throwError
的更多信息。从技术上讲,这些应该会冒出来。实际学习的最佳方法是自己编写代码,我建议您创建一个名为login $()的冷可观察对象,它可以完成您应该做的所有事情。仅在其上调用.subscribe()会返回completed可观察的。
由于其他人已经对编码进行了评论,因此在这里我不会进行编码,但是您应该尝试一下!