Как сделать asyn c вызов внутри другого asyn c вызова с циклом foreach - PullRequest
0 голосов
/ 19 марта 2020

Я действительно хочу улучшить и понять, как сделать это лучше. Этот код работает, но я считаю, что здесь что-то не так. Идея заключается в следующем:

1: я делаю первый HTTP-вызов API и получаю данные.

2: я использую данные matchHistoryArr с массивом 10 " gameIds ", и мне нужно передать их через forEach (l oop) в this.summ.getMatches (gameId) и pu sh их в новый локальный массив, необходимый для сравнения с другим массивом для его сортировки (потому что asyn c не дает сортировать) так что после долгих поисков я мог бы решить это следующим образом. (Я собираюсь отметить в коде) note : это место, где у меня возникла большая проблема,

3: Теперь мне нужно получить больше данных с других конечных точек, но Я считаю, что перед тем, как продолжить, я должен заказать код лучше.

Component.ts

     onSubmit(){
** 1 **
    this.summ.getSummoner(this.summoner.name,this.summoner.regionId)
    .subscribe(  (data:any) => {

      let matchHistoryArr = data.matchHistory

      let gameIdArray = matchHistoryArr.map( element => element.gameId)

      const subscribers: Subscriber<any>[] = [];
        const promiseMatchesArray = [];

** 2 **
       matchHistoryArr.forEach( element => {

         promiseMatchesArray.push( this.summ.getMatches(element.gameId).toPromise().then( match => {

           subscribers.push(match)
         }));
         });

           Promise.all(promiseMatchesArray).then( a =>{
               if ( subscribers.length === matchHistoryArr.length ){

                let arraySort = [];
                arraySort = subscribers
                let dataParticipants

                  let matchesArraySorted = arraySort.sort((a, b) => {  
                   return gameIdArray.indexOf(a.gameId) - gameIdArray.indexOf(b.gameId);
                 });

                 this.matchesArray = matchesArraySorted

                 matchesArraySorted.forEach( x => {

                  dataParticipants = x.participants
                  });

                  if ( dataParticipants.length === 10 ){

                    this.dataParticipants = dataParticipants
                  }
               }
           });


      this.matchHistory = matchHistoryArr
      this.SummInfo = data.summonerdata;

     });

  }

Services.ts

export class SummonerService {

  constructor( private http:HttpClient ) { }

  summonerName

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



   getChampImage(champId){
     return this.http.get(`https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/v1/champion-icons/${champId}.png`)
   };

   getMatches(gameId){
     return this.http.get( `http://localhost:3000/match/${gameId}` )
     .pipe( 
       map( (data:any) => this.uploadData(data))
       )};

1 Ответ

0 голосов
/ 19 марта 2020

По сути, ваш пример можно свести к двум шагам:

  1. Получить данные из наблюдаемой
  2. Выполнить набор вызовов на основе данных от 1.

Я бы рекомендовал все время придерживаться наблюдаемых, если нет веских причин для использования обещаний.

  1. Сделайте начальный вызов, как вы делаете 1a. Переключитесь на новую наблюдаемую команду, используя concatMap
  2. Создайте массив наблюдаемых и запустите параллельно, используя forkJoin
onSubmit() {
  this.summ.getSummoner(this.summoner.name, this.summoner.regionId)
    .pipe(
      tap((summoner) => this.matchHistory = summoner.matchHistory),
      concatMap((summoner: any) => {
        const observables = this.matchHistory
          .map(element => this.summ.getMatches(element.gameId));
        return forkJoin(observables)
      }),
      map(matchesArray => {
        // TODO: perform sorting
        return matchesArray;
      })
    ).subscribe(matchesArray => {

    });
}

Я упустил вашу сортировку, чтобы сделать ответ простым.

matchesArray - это массив результатов, отражающих ввод observables.

Любая сортировка, которую вы хотите выполнить, может быть выполнена с помощью оператора map.

Any состояние, которое вы хотите сохранить из канала, может быть выполнено с помощью оператора tap.

Ключом к объединению наблюдаемых является помнить, что существует только один подписчик верхнего уровня. Observables можно комбинировать практически любым способом, который вы можете использовать с помощью операторов pipe. Вот почему я рекомендую придерживаться наблюдаемых. Они более мощные, чем обещания в сложном сценарии ios.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...