Javascript 如何使用Angular在同一个函数中进行多个http调用

Javascript 如何使用Angular在同一个函数中进行多个http调用,javascript,angular,typescript,rxjs,angular8,Javascript,Angular,Typescript,Rxjs,Angular8,我想要实现的目标: 从component.ts调用服务this.getMatches,在this.getMatches中,我必须进行一些API调用并处理我得到的数据 在它被推送到数组之前 我所做的: 1:函数运行并将“gameId”作为参数发送给函数this.getmatches。我得到了每个匹配的数组,其中包含我推送到每个匹配的所有数据 2:我在多次尝试后找到了一个有效的方法,但当它返回数组时失败了 问题: 有时它返回相同的匹配,我注意到当我添加“swtichmap”操作符时会发生这种情况

我想要实现的目标: 从component.ts调用服务this.getMatches,在this.getMatches中,我必须进行一些API调用并处理我得到的数据 在它被推送到数组之前

我所做的: 1:函数运行并将“gameId”作为参数发送给函数this.getmatches。我得到了每个匹配的数组,其中包含我推送到每个匹配的所有数据 2:我在多次尝试后找到了一个有效的方法,但当它返回数组时失败了

问题: 有时它返回相同的匹配,我注意到当我添加“swtichmap”操作符时会发生这种情况

Services.ts

@Injectable({
  providedIn: 'root'
})
export class SummonerService {

  constructor( private http:HttpClient ) { }

  summonerName
  dataMatch
  matchParticipants
  matchHistory = [];

    getSummoner(summonerName,regionId){
    this.summonerName = summonerName
   return this.http.get(`http://localhost:3000/summName/${summonerName}/${regionId}` )
  };

   getMatches(gameId){
     return this.http.get( `http://localhost:3000/match/${gameId}` 
     ).pipe(
       tap( (data:any) => {
         console.log(data.match);
         this.dataMatch = data.match
         this.matchParticipants = data.match.participants
        }) ,
       switchMap( data => {
         return this.http.get(`http://ddragon.leagueoflegends.com/cdn/10.5.1/data/en_US/summoner.json`)
       }),
       tap( (data:any) =>{


         let spellsObj = data.data;
         const spellsArray:Array<any>[] = [];

         Object.keys(spellsObj).forEach( key =>{

           let spell = spellsObj[key]

           spellsArray.push(spell)
          });

          this.matchParticipants.forEach( participants => {

            let spellId1:any = spellsArray.find( (spell:any) => spell.key === JSON.stringify(participants.spell1Id) );
            let spellId2:any = spellsArray.find( (spell:any) => spell.key === JSON.stringify(participants.spell2Id) );


            let spellId1Image = `http://ddragon.leagueoflegends.com/cdn/10.5.1/img/spell/${spellId1.id}.png`
            let spellId2Image = `http://ddragon.leagueoflegends.com/cdn/10.5.1/img/spell/${spellId2.id}.png`

            participants.spellId1Info = spellId1
            participants.spellId2Info = spellId2

            participants.spellId1Info.image = spellId1Image
            participants.spellId2Info.image = spellId2Image
    });
       }),
       map ( data =>{ 
          return this.dataMatch
         })
       )};
onSubmit( ){

    this.summ.getSummoner( this.summoner.name,this.summoner.regionId )
    .pipe( 
      tap( (summoner:any) => this.matchHistory = summoner.matchHistory ),
      concatMap( (summoner:any) => {
        const observables = this.matchHistory
        .map( element => this.summ.getMatches(element.gameId));
          return forkJoin(observables)
      }),
      map( (matchesArray:any) => {
        let gameIdArray = this.matchHistory.map( element => element.gameId)

        this.matchesArray = matchesArray.sort((a, b) => {  
          return gameIdArray.indexOf(a.gameId) - gameIdArray.indexOf(b.gameId);
        });
        return matchesArray
      })
      ) .subscribe();
我也不知道这里的“开关图”通话是否正确

组件。ts

@Injectable({
  providedIn: 'root'
})
export class SummonerService {

  constructor( private http:HttpClient ) { }

  summonerName
  dataMatch
  matchParticipants
  matchHistory = [];

    getSummoner(summonerName,regionId){
    this.summonerName = summonerName
   return this.http.get(`http://localhost:3000/summName/${summonerName}/${regionId}` )
  };

   getMatches(gameId){
     return this.http.get( `http://localhost:3000/match/${gameId}` 
     ).pipe(
       tap( (data:any) => {
         console.log(data.match);
         this.dataMatch = data.match
         this.matchParticipants = data.match.participants
        }) ,
       switchMap( data => {
         return this.http.get(`http://ddragon.leagueoflegends.com/cdn/10.5.1/data/en_US/summoner.json`)
       }),
       tap( (data:any) =>{


         let spellsObj = data.data;
         const spellsArray:Array<any>[] = [];

         Object.keys(spellsObj).forEach( key =>{

           let spell = spellsObj[key]

           spellsArray.push(spell)
          });

          this.matchParticipants.forEach( participants => {

            let spellId1:any = spellsArray.find( (spell:any) => spell.key === JSON.stringify(participants.spell1Id) );
            let spellId2:any = spellsArray.find( (spell:any) => spell.key === JSON.stringify(participants.spell2Id) );


            let spellId1Image = `http://ddragon.leagueoflegends.com/cdn/10.5.1/img/spell/${spellId1.id}.png`
            let spellId2Image = `http://ddragon.leagueoflegends.com/cdn/10.5.1/img/spell/${spellId2.id}.png`

            participants.spellId1Info = spellId1
            participants.spellId2Info = spellId2

            participants.spellId1Info.image = spellId1Image
            participants.spellId2Info.image = spellId2Image
    });
       }),
       map ( data =>{ 
          return this.dataMatch
         })
       )};
onSubmit( ){

    this.summ.getSummoner( this.summoner.name,this.summoner.regionId )
    .pipe( 
      tap( (summoner:any) => this.matchHistory = summoner.matchHistory ),
      concatMap( (summoner:any) => {
        const observables = this.matchHistory
        .map( element => this.summ.getMatches(element.gameId));
          return forkJoin(observables)
      }),
      map( (matchesArray:any) => {
        let gameIdArray = this.matchHistory.map( element => element.gameId)

        this.matchesArray = matchesArray.sort((a, b) => {  
          return gameIdArray.indexOf(a.gameId) - gameIdArray.indexOf(b.gameId);
        });
        return matchesArray
      })
      ) .subscribe();

switchMap
我觉得这里很不错,如果您对此不确定,请随时查看我关于此主题的博文:

如果要发出多个请求,则需要在
开关映射
中应用组合运算符,可能是
合并
forkJoin
。代码可能如下所示:

 switchMap( data => merge(
    this.http.get(`http://x.json`),
    this.http.get(`http://y.json`),
    this.http.get(`http://z.json`)
)),
所以问题是你想用哪一个:

当您不关心其他HTTP调用是否已经完成时,您希望使用。每次这些HTTP请求中的一个返回响应时,您将在switchMap之后得到一个新值,并且您也将只得到该响应


当您关心在进行一个HTTP调用之前完成所有HTTP调用时,您希望使用。您还将获得一系列HTTP响应,您可以使用这些响应继续处理。

您能做一个简单的stackblitz,演示您的问题,让我们看看吗?