Angular 如何减少订阅操作符的数量并用不同的rxjs操作符替换
尝试减少订阅的数量,并使用等效的flatMap\switchMap\do\taprxjs运算符来处理以下代码。 这是可行的,但我知道这不是最好的方法。 该守则的作用如下: 首先-进行凭证检查(usename和pass): A.如果它获取用户数据,它会重置登录尝试次数-将登录尝试次数重置为0,并路由到不同的路由。 B.如果不是(A)-增加登录尝试次数-将登录尝试次数增加1。服务将在增量后获取登录次数。根据它的检查-如果登录尝试>=3,那么它将生成CaptCha,这也将返回observableAngular 如何减少订阅操作符的数量并用不同的rxjs操作符替换,angular,rxjs,angular2-observables,Angular,Rxjs,Angular2 Observables,尝试减少订阅的数量,并使用等效的flatMap\switchMap\do\taprxjs运算符来处理以下代码。 这是可行的,但我知道这不是最好的方法。 该守则的作用如下: 首先-进行凭证检查(usename和pass): A.如果它获取用户数据,它会重置登录尝试次数-将登录尝试次数重置为0,并路由到不同的路由。 B.如果不是(A)-增加登录尝试次数-将登录尝试次数增加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调用实际上不应该被链接,那么订阅。但是,如果你要打两个电话,是的,你应该一起打concatMap
另一件可以清理代码的事情是知道流是否真正完成。在我看来,这是RXJS中的一个缺陷,不知道您所做的调用是一次性的,还是实际上是一个流
如果您发出一个http请求,并且不希望保持流打开,那么您就不必保留对任何RXJS调用的订阅。但是,如果您计划保持流打开,我建议使用ngondestry
技术。
你可以阅读更多关于它的内容,也许你应该看看相同的概念,但告诉你相反的东西:)
此外,您还应该阅读更多关于您的投手的信息。从技术上讲,这些应该是泡沫。实际学习的最好方法是自己编写代码,我建议您创建一个名为login$()的冷可观察对象,它完成您应该做的所有事情。仅对其调用.subscribe()将返回一个已完成的可观察值
//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)));
}
由于其他人已经对如何编写代码发表了评论,所以我不会在这里编写代码,但您应该试一试 你有什么理由保留对订阅的引用吗?我假设你让他们在销毁时退订?正确-这就是原因-我在Ngondestory()事件中这么做谢谢你的评论-我确实使用Ngondestory技术(代码中没有提到)退订。