Angular 7中如何从Subscribe存储外部变量并在其他类读取
解决跨类访问异步加载数据的问题
我来帮你搞定这个问题~首先得提醒你:你的原代码里,myExternalVar是通过异步的HTTP请求赋值的,要是直接从另一个类访问它,大概率会碰到**数据还没加载完成就拿到undefined**的情况。下面给你两种靠谱的解决方案,都是前端项目里常用的实践:
方案一:用共享服务(推荐)
类之间共享数据最规范的方式就是用服务,我们可以借助BehaviorSubject来实现数据的实时同步:
1. 创建数据共享服务
import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataShareService { // 用BehaviorSubject保存数据,初始值设为null private dataStore = new BehaviorSubject<any>(null); // 对外暴露Observable,避免外部直接修改数据 public data$: Observable<any> = this.dataStore.asObservable(); // 更新数据的方法 updateSharedData(data: any): void { this.dataStore.next(data); } }
2. 修改原类的loadData方法
把请求到的数据同步到共享服务里:
import { DataShareService } from './data-share.service'; import { merge, of } from 'rxjs'; import { startWith, switchMap, catchError } from 'rxjs/operators'; export class YourOriginalClass { constructor( private myService: YourDataService, private dataShareService: DataShareService ) {} loadData(id: string): void { merge() .pipe( startWith({}), switchMap(() => this.myService.getData(id)), catchError(() => of([])) ) .subscribe(data => { // 将数据同步到共享服务 this.dataShareService.updateSharedData(data); }); } }
3. 在另一个类中读取数据
通过订阅共享服务的data$,实时获取最新数据:
import { DataShareService } from './data-share.service'; export class AnotherClass { currentData: any; constructor(private dataShareService: DataShareService) { // 订阅数据变化,确保拿到最新的异步数据 this.dataShareService.data$.subscribe(data => { this.currentData = data; // 这里可以写数据加载完成后的逻辑,比如渲染UI、处理业务 }); } }
方案二:在原类中暴露Observable(适合简单场景)
如果不想新增服务,也可以在原类里自己维护一个BehaviorSubject,对外提供获取数据的Observable:
import { merge, of, BehaviorSubject, Observable } from 'rxjs'; import { startWith, switchMap, catchError } from 'rxjs/operators'; export class YourOriginalClass { private dataSubject = new BehaviorSubject<any>(null); // 对外暴露Observable public data$: Observable<any> = this.dataSubject.asObservable(); constructor(private myService: YourDataService) {} loadData(id: string): void { merge() .pipe( startWith({}), switchMap(() => this.myService.getData(id)), catchError(() => of([])) ) .subscribe(data => { this.dataSubject.next(data); }); } }
然后在另一个类中注入原类(注意要确保原类已经初始化并调用过loadData):
import { YourOriginalClass } from './your-original-class'; export class AnotherClass { currentData: any; constructor(private originalClass: YourOriginalClass) { this.originalClass.data$.subscribe(data => { this.currentData = data; }); } }
关键提醒
- 永远不要直接访问另一个类的变量来拿异步数据!因为HTTP请求是异步的,你访问的时候数据可能还没加载好。
- 推荐用共享服务的方案,它遵循单一职责原则,能避免类之间的耦合,也是官方推荐的跨类数据共享方式。
内容的提问来源于stack exchange,提问作者Jake Weary
相关产品推荐
相关产品推荐

