You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular14中RxJS等待接口响应后执行后续代码的问题

解决方案:利用RxJS异步流等待服务变量更新

你的问题根源在于HTTP请求是异步操作,组件调用getAuthenticatedUserProfile()后会立即执行后续代码,此时API还未返回数据,服务中的auth变量仍为初始值。浏览器控制台展开对象时会读取最新状态,所以会出现"初始显示null,展开后有值"的现象。

下面提供两种不依赖localStorage的RxJS解决方案:


方案一:让服务返回Observable,组件订阅后执行后续逻辑

这种方式最直接,将HTTP请求的Observable返回给组件,由组件在请求完成的回调中处理后续操作。

修改服务代码

移除服务内的subscribe,改用tap操作符处理变量更新和store派发,最终返回Observable:

getAuthenticatedUserProfile(): Observable<any> {
  return this._http
    .get(`${environment.apiUrl}/user/state-profile`, {
      headers: GlobalHeaders.HTTP_HEADERS,
      observe: 'response',
      responseType: 'json',
      withCredentials: true
    })
    .pipe(
      tap((data: any) => {
        let auth = data.body?.data;
        let payload = {
          userId: auth?.user_id,
          userName: auth?.user_name,
          userFullName: auth?.name,
          userEmail: auth?.email,
          roleName: auth?.role,
          profileId: auth?.profile_id,
          profileName: auth?.profile_name,
          userZone: auth?.zones,
          userState: auth?.states,
          userDistrict: auth?.districts,
          userAccessMenu: auth?.user_menus,
          allMenu: auth?.all_menus,
          isOtpRequired: auth?.require_otp,
          isLoggedIn: true
        };
        this.auth = payload;
        this._store.dispatch(new UpdateAuthAction(payload));
      })
    );
}

修改组件代码

订阅服务返回的Observable,在next回调中执行路由等后续逻辑:

constructor(private renderer: Renderer2, private _authService: AuthService, private router: Router) {}

ngOnInit(): void {
  let configItems = JSON.parse(localStorage.getItem('appConfig') || '{}');
  this.appName = configItems.appName || 'Demo App';
  this.otpForm = new UntypedFormGroup({
    otp: new UntypedFormControl(null,[ Validators.required, Validators.pattern(/^\d{1,6}$/)])
  });

  // 订阅请求结果,等待数据返回后执行后续代码
  this._authService.getAuthenticatedUserProfile().subscribe({
    next: () => {
      console.log(this._authService.auth); // 此时auth已更新
      const auth = this._authService.auth;
      if (!auth.isLoggedIn || !auth.isOtpRequired) {
        this.router.navigate(['/dashboard']);
      }
    },
    error: (err) => {
      // 处理请求失败的情况,比如跳转登录页
      console.error('获取用户信息失败', err);
      this.router.navigate(['/login']);
    }
  });
}

方案二:用BehaviorSubject发布状态更新(适合多组件监听场景)

如果你的应用中有多个组件需要监听auth状态变化,可以在服务中使用BehaviorSubject来发布状态,组件订阅这个Subject获取最新值。

修改服务代码

添加BehaviorSubject用于发布auth状态:

import { BehaviorSubject, Observable } from 'rxjs';

// 定义BehaviorSubject,初始值为null
private authSubject = new BehaviorSubject<any>(null);
// 对外暴露可观察对象,防止外部直接修改Subject
public auth$ = this.authSubject.asObservable();

getAuthenticatedUserProfile() {
  return this._http
    .get(`${environment.apiUrl}/user/state-profile`, {
      headers: GlobalHeaders.HTTP_HEADERS,
      observe: 'response',
      responseType: 'json',
      withCredentials: true
    })
    .subscribe({
      next: (data: any) => {
        let auth = data.body?.data;
        let payload = {
          userId: auth?.user_id,
          userName: auth?.user_name,
          userFullName: auth?.name,
          userEmail: auth?.email,
          roleName: auth?.role,
          profileId: auth?.profile_id,
          profileName: auth?.profile_name,
          userZone: auth?.zones,
          userState: auth?.states,
          userDistrict: auth?.districts,
          userAccessMenu: auth?.user_menus,
          allMenu: auth?.all_menus,
          isOtpRequired: auth?.require_otp,
          isLoggedIn: true
        };
        this.auth = payload;
        this.authSubject.next(payload); // 发布状态更新
        this._store.dispatch(new UpdateAuthAction(payload));
      },
      error: (err) => {
        this.authSubject.error(err); // 传递错误信息
      }
    });
}

修改组件代码

订阅服务的auth$ Observable,等待状态更新:

constructor(private renderer: Renderer2, private _authService: AuthService, private router: Router) {}

ngOnInit(): void {
  let configItems = JSON.parse(localStorage.getItem('appConfig') || '{}');
  this.appName = configItems.appName || 'Demo App';
  this.otpForm = new UntypedFormGroup({
    otp: new UntypedFormControl(null,[ Validators.required, Validators.pattern(/^\d{1,6}$/)])
  });

  // 触发请求
  this._authService.getAuthenticatedUserProfile();
  
  // 订阅auth状态变化
  this._authService.auth$.subscribe({
    next: (auth) => {
      if (auth) { // 确保auth已完成更新
        console.log(auth);
        if (!auth.isLoggedIn || !auth.isOtpRequired) {
          this.router.navigate(['/dashboard']);
        }
      }
    },
    error: (err) => {
      console.error('获取用户信息失败', err);
      this.router.navigate(['/login']);
    }
  });
}

内容的提问来源于stack exchange,提问作者Nirjhar Mistry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 04:25:17