Google社交登录函数执行顺序异常及重复调用问题求助
解决方案:Google社交登录函数的异步执行与重复调用问题
问题分析
- 异步执行顺序问题:
this.loginGoogle($event)是同步执行,而socialAuthService.signIn是异步操作,authState的回调会在登录流程完成后才触发,导致loginGoogle先执行时还未拿到用户数据。 - 重复调用问题:每次点击都会新增一个
authState订阅,多次点击后订阅累积,后续authState变化时所有订阅都会触发,导致loginGoogle被重复调用。
方案一:使用RxJS take(1)自动取消订阅
利用RxJS的take(1)操作符,确保只订阅一次authState的第一个值,自动完成并取消订阅,同时将loginGoogle放在订阅回调内,保证拿到用户数据后再执行。
修改后的代码:
import { take } from 'rxjs'; // ... loginnn($event){ // 阻止默认事件(如表单提交、页面跳转) $event.preventDefault(); this.socialAuthService.signIn(GoogleLoginProvider.PROVIDER_ID); this.socialAuthService.authState .pipe(take(1)) // 仅取第一个值后自动取消订阅 .subscribe((user) => { if (!user) return; // 处理用户取消登录的情况 this.frmLoginGoogle.patchValue({ email: user.email, googleAuthToken: user.authToken, }); this.loginGoogle($event); // 拿到用户数据后执行登录逻辑 }); }
方案二:手动管理订阅生命周期
如果需要更灵活的订阅控制,可以手动维护订阅对象,每次调用前取消旧订阅,组件销毁时也清理订阅,避免内存泄漏。
代码示例:
import { Subscription } from 'rxjs'; // 组件类内定义订阅对象 private authSubscription: Subscription | undefined; loginnn($event){ $event.preventDefault(); // 取消之前的订阅,避免重复触发 this.authSubscription?.unsubscribe(); this.socialAuthService.signIn(GoogleLoginProvider.PROVIDER_ID); this.authSubscription = this.socialAuthService.authState.subscribe((user) => { if (!user) return; this.frmLoginGoogle.patchValue({ email: user.email, googleAuthToken: user.authToken, }); this.loginGoogle($event); // 执行登录后手动取消订阅,防止后续状态变化再次触发 this.authSubscription?.unsubscribe(); }); } // 组件销毁时清理订阅 ngOnDestroy() { this.authSubscription?.unsubscribe(); }
内容的提问来源于stack exchange,提问作者Leonardo Lima
相关产品推荐
相关产品推荐

