Angular 获取和存储全局变量

Angular 获取和存储全局变量,angular,Angular,我正在努力解决一个简单的概念,我可以用C#轻松地完成,但不能用Angular 我试图将用户配置文件存储在我在每个组件中添加的服务中,因此我不会在每次加载/显示组件时都获取配置文件 因此,我创建了一个服务,其中构造函数获取用户配置文件,并将其保存在一个变量中,并对我的所有组件使用getter 我遇到的问题是,当组件调用getter时,变量是net set,因为服务还没有响应。这会导致未定义的错误并破坏组件,因为配置文件在组件代码中至关重要 在C#中,我只需在获取概要文件时放入1 wait,这样其他

我正在努力解决一个简单的概念,我可以用C#轻松地完成,但不能用Angular

我试图将用户配置文件存储在我在每个组件中添加的服务中,因此我不会在每次加载/显示组件时都获取配置文件

因此,我创建了一个服务,其中构造函数获取用户配置文件,并将其保存在一个变量中,并对我的所有组件使用getter

我遇到的问题是,当组件调用getter时,变量是net set,因为服务还没有响应。这会导致未定义的错误并破坏组件,因为配置文件在组件代码中至关重要

在C#中,我只需在获取概要文件时放入1 wait,这样其他所有内容都可以不等待地运行,因为我知道数据就在那里

但在我看来,我试过了,但似乎不起作用

export class SharedService {
  private userProfile;
  constructor(private http: HttpService) {
    this.initProfile();
  }
  async initProfile(): Promise < void > {   
    this.userProfile =await this.http.getProfile().subscribe((data: any) => {
       //...
    }
  });

  getUserProfile() {
    return this.userProfile;
  }
} 
在组件中,当我调用getUserProfile函数时,服务会立即使用空的userProfile进行应答

编辑: 我使用非常讨厌的代码片段成功地实现了所需的行为,但这应该清楚地表明我正在尝试实现什么。在my profile.component.ts中:

async ngOnInit(): Promise<void>  {    
 while (this.profile == null) {
  await this.sharedService.sleep(500);
  this.profile = this.sharedService.getUserProfile();    
 }
 if (this.profile.isadmin){
  this.CalculateStuff();
 }
 //
 //imagine here even more code using the this.profile variable in if statements, 
 //cases, etc.
 //
}

事实上,我必须编写一个睡眠函数来实现这一点,这对我来说是一个明确的信号,表明我做错了什么。这就是我来这里的原因。

你就快到了。您正在等待的订阅不适用于
async
/
wait
。只需执行以下操作。把它转换成承诺,这样你就可以等待它了

async ngOnInit(): Promise<void>  {  
  this.profile = await this.sharedService.getUserProfile().toPromise();    
 if (this.profile.isadmin){
  this.CalculateStuff();
 }
}

同样如前所述,RxJs的基本知识将非常有用,可以解决许多早期问题

另一种方法是使服务中的
userProfile
成为可观察的多播(如带有缓冲区1的RxJS
ReplaySubject
)。这样就不需要将可观察到的东西与承诺混为一谈

服务

从'rxjs'导入{ReplaySubject};
导出类共享服务{
private userProfile=新的ReplaySubject(1);
构造函数(私有http:HttpService){
this.initProfile();
}
initProfile(){
这是.http.getProfile().subscribe({
下一步:(数据:任意)=>{

this.userProfile.next(data);//{}//如果您喜欢使用承诺,请将observable转换为promise:
this.userProfile=wait this.http.getProfile().toPromise()
;应该更好你不能
等待订阅或观测并获得结果值,这只适用于承诺。你可以按照@Andrei的建议使用
.toPromise
,或者倾向于RxJS(因为角度的大部分是基于观测值的,我建议后者)。谢谢你的回复。我正在努力避免将我所有的代码都放在订阅答案中。如前所述,很多代码取决于配置文件的内容,因此,在发布之前,这就是我所做的。只要服务中没有设置userprofile,难道不可能简单地停止代码执行流吗?因为ng else取决于它。还是我遗漏了什么?如果您需要代码中的值来做出决策,您如何处理承诺?是的,这在我回答中的第一段代码中是可能的(订阅也是可能的,但有点复杂)。当您将可观察内容转换为承诺并等待它时。您的函数将等待承诺完成(成功或抛出错误)。承诺将完成,然后您可以像“正常”一样使用
this.userProfile
变量。很抱歉,是的,您是对的,代码块正在停止。我的问题表述得很糟糕。我的意思是,我的组件似乎没有等待代码执行完毕。它将从共享服务获取未定义/未设置的用户配置文件,即使共享服务仍在“等待”在http服务的getprofile上。啊,是的。这是Angular中异步代码的一个基本部分。您需要使用
ngIf=“userProfile”
在模板中进行空检查(这是不需要的)为了避免尝试使用空值执行任何操作。当配置文件承诺完成时,该值将不再为空,模板将对新的“非空”配置文件执行更新。您能否提供一个代码示例,说明到底是什么导致了问题?好的。再次感谢您抽出时间!我肯定需要提出一些建议(很多?)在rxjs中,这听起来像是一门外语:(但谢谢你把这篇文章写出来。等我对rxjs有了更好的了解后,我会再讨论它。希望很快!@Hedi:虽然这篇文章可以提供有价值的参考,但我不推荐它作为一个起点。它们是用来补充现有知识的直截了当的信息。相反,你可以开始使用。它们为每一个乐趣提供了更多的上下文。)操作和运算符,并提供易于掌握的示例。您还可以使用来补充LearnRxJS。再次感谢您提供的信息。我将为您的评论添加书签,并在启动RXJS时返回!
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
async ngOnInit(): Promise<void>  {  
  this.profile = await this.sharedService.getUserProfile().toPromise();    
 if (this.profile.isadmin){
  this.CalculateStuff();
 }
}
  this.http.getProfile().subscribe((userProfile: any) => {
       // do userProfile actions here
  });
  //Since subscribe is an async callback, anything outside that block will have userProfile undefined.