Angular 角度异步函数OnInit

Angular 角度异步函数OnInit,angular,typescript,asynchronous,httprequest,Angular,Typescript,Asynchronous,Httprequest,希望你今天过得愉快。我在处理ngOninit上的异步调用时遇到了这个问题。基本上,我需要按顺序加载一些东西,但我不知道如何加载。 代码如下: 从“@angular/core”导入{Component,OnInit}; 从“../../models/Match”导入{Match,Game,participatities,player}; 从“../../services/match.service”导入{MatchService}; 从“../../services/Global”导入{Glob

希望你今天过得愉快。我在处理ngOninit上的异步调用时遇到了这个问题。基本上,我需要按顺序加载一些东西,但我不知道如何加载。 代码如下:

从“@angular/core”导入{Component,OnInit}; 从“../../models/Match”导入{Match,Game,participatities,player}; 从“../../services/match.service”导入{MatchService}; 从“../../services/Global”导入{Global}; 从“rxjs”导入{Observable}; @组成部分{ 选择器:“应用程序播放器”, templateUrl:“./players.component.html”, 样式URL:['./players.component.css'], 提供者:[匹配服务] } 导出类PlayerComponent实现OnInit{ 公共匹配:数组; 公共游戏:阵列 公共玩家:阵列; 公众玩家:[] 建造师 私有匹配服务:匹配服务 { 这个。游戏=[] this.player=[] } 恩戈尼尼特:空虚{ 这是getMatchs } getMatchs{ 这是。_matchService.getMatchs.subscribe 响应=>{ this.matchs=response.matchs; console.logthis.matchs; forlet i=0;i{ 控制台日志错误 } ; } getUsers{ 让accountId=[]; forlet i=0;ielement==this.matchs[i].game.participatienties[x].player.calluername==未定义{ accountId.pushthis.matchs[i]。游戏。参与者身份[x]。玩家。召唤名称 this.player.pushthis.matchs[i].game.participatities[x].player } } } console.logthis.player } } 一种方法是将getUsers放在this.matchs=response.matchs;之后,然后每次调用getMatchs时,它也会调用getUsers

另一种方法是将订阅转移到ngOnInit

恩戈尼尼特:空虚{ this.getMatchs.subscriberResponse=>{ this.matchs=response.matchs; forlet i=0;ielement==this.matchs[i]。游戏。参与者身份[x]。玩家。召唤名称===未定义{ accountId.pushthis.matchs[i]。游戏。参与者身份[x]。玩家。召唤名称 this.player.pushthis.matchs[i].game.participatities[x].player } } } console.logthis.player } 一种方法是将getUsers放在this.matchs=response.matchs;之后;,然后每次调用getMatchs时,它也会调用getUsers

另一种方法是将订阅转移到ngOnInit

恩戈尼尼特:空虚{ this.getMatchs.subscriberResponse=>{ this.matchs=response.matchs; forlet i=0;ielement==this.matchs[i]。游戏。参与者身份[x]。玩家。召唤名称===未定义{ accountId.pushthis.matchs[i]。游戏。参与者身份[x]。玩家。召唤名称 this.player.pushthis.matchs[i].game.participatities[x].player } } } console.logthis.player }
@satanTime的解决方案很好。 但是,我想提供另一种解决方案,以防您不想错误地调用getUsers

你可以尝试使用承诺

它变得更具可读性

找火柴。完成后,获取用户

仅仅为了完成和幻想,您可以将_matchService.getMatchs上返回的可观察内容转换为承诺,完成它,然后返回它

getMatchs = (): Promise<void> => 
    this._matchService.getMatchs().toPromise()
        .then(response => {
            // Do whatever you need
        })
        .catch(err => {
            // Handle error
        });

希望有帮助。

@satanTime的解决方案很好。 但是,我想提供另一种解决方案,以防您不想错误地调用getUsers

你可以尝试使用承诺

它变得更具可读性

找火柴。完成后,获取用户

仅仅为了完成和幻想,您可以将_matchService.getMatchs上返回的可观察内容转换为承诺,完成它,然后返回它

getMatchs = (): Promise<void> => 
    this._matchService.getMatchs().toPromise()
        .then(response => {
            // Do whatever you need
        })
        .catch(err => {
            // Handle error
        });

希望能有所帮助。

正如您所见,有几种不同的解决方案可以解决您的问题。我的建议是继续使用可观察链,直到您完成匹配。例如:

ngOnInit(): void {
  this.getMatchs().subscribe(res => this.getUsers());
}
然后您必须更改getmatchs函数,如下所示:

getMatchs() {
  this._matchService.getMatchs().pipe(
    tap(result => {
      this.matchs = response.matchs;
      this.games = this.matchs.map(m => m.game);
    })
  );  
通过这样做,您可以继续使用您的可观察流

这应该行得通,但还有其他问题需要注意。其中之一是,为了避免应用程序内存泄漏,取消订阅每个订阅是一个非常好的做法。您可以通过手动调用unsubscribe或依赖angular的异步管道来实现这一点

另一方面,如果您可以修改代码以减少对相同信息执行的循环数量,您将获得更好的性能。查看我为您编写的未经测试的GetMatchs的另一个版本,希望它能让您了解如何提高组件的性能:

processMatches() {
   this._matchService.getMatches().pipe(
      tap(response => {
         this.matches = response.matchs;
         let accountId = {};            

         this.matches.forEach((m, index) => {
            this.game[index] = m[index].game;
            this.game[index].participantIdentities
                .forEach(p => {
                    if (!accountId[p.player.sumonerName]) {
                        accountId[p.player.sumonerName] = p.player.sumonerName;
                        this.player.push(p.player);
                    }
                });      
             });

         })
     )
 }
同样,这段代码没有经过测试,因为这里的想法是减少循环,并将accountId数组转换为一个对象,以便更轻松地检查重复项 斯特


快乐编码

正如您所见,您的问题有几种不同的解决方案。我的建议是继续使用可观察链,直到您完成匹配。例如:

ngOnInit(): void {
  this.getMatchs().subscribe(res => this.getUsers());
}
然后您必须更改getmatchs函数,如下所示:

getMatchs() {
  this._matchService.getMatchs().pipe(
    tap(result => {
      this.matchs = response.matchs;
      this.games = this.matchs.map(m => m.game);
    })
  );  
通过这样做,您可以继续使用您的可观察流

这应该行得通,但还有其他问题需要注意。其中之一是,为了避免应用程序内存泄漏,取消订阅每个订阅是一个非常好的做法。您可以通过手动调用unsubscribe或依赖angular的异步管道来实现这一点

另一方面,如果您可以修改代码以减少对相同信息执行的循环数量,您将获得更好的性能。查看我为您编写的未经测试的GetMatchs的另一个版本,希望它能让您了解如何提高组件的性能:

processMatches() {
   this._matchService.getMatches().pipe(
      tap(response => {
         this.matches = response.matchs;
         let accountId = {};            

         this.matches.forEach((m, index) => {
            this.game[index] = m[index].game;
            this.game[index].participantIdentities
                .forEach(p => {
                    if (!accountId[p.player.sumonerName]) {
                        accountId[p.player.sumonerName] = p.player.sumonerName;
                        this.player.push(p.player);
                    }
                });      
             });

         })
     )
 }
同样,这段代码没有经过测试,因为这里的想法是减少循环,并将accountId数组转换为一个对象,以便更容易、更快地检查重复项


快乐编码

非常有用的信息,我没有想到使用.map。我还不完全了解它是如何工作的。我在我的程序的一些实例中遇到了这个问题,所以我越了解它越好。Thx很多。非常有用的信息,我没有想到使用。map我还不完全了解它是如何工作的。我在我的程序的一些实例中遇到了这个问题,所以我越了解它越好。Thx很多。是的,这很有帮助,我一直在寻找如何正确使用承诺,但没有多大成功,我最终做出了与@satanTime的建议类似的东西。我还有很多工作要做,所以欢迎提供任何信息。Thx很多。是的,这很有帮助,我一直在寻找如何正确使用承诺,但没有多大成功,我最终做出了与@satanTime的建议类似的东西。我还有很多工作要做,所以欢迎提供任何信息。Thx很多。很高兴听到,这不是一个理想的解决方案,只是一个简单的例子来展示一种可能的解决方法。如果我能在这里提供更多帮助,请随时告诉我。很高兴听到,这不是一个理想的解决方案,只是一个简单的例子来展示一种可能的解决方法。如果我能在这里提供更多帮助,请随时告诉我。