Angular 4 ждет обещания/наблюдаемого в цикле

Я не могу найти действительное решение для следующего случая

Я хочу создать следующий цикл:

  1. ForEach элемент (A) массива
  2. Заполнить новый массив (B)
  3. Если ключ не существует в массиве (B), вызовите службу Firebase для получения данных
  4. Проверить данные и обновить статистику
  5. в конце всего (A) ключа сгенерируйте статистику выполнения и выставьте...

Мне нужно подождать и связать ответ данных Firebase, прежде чем продолжить цикл, и проблема в том, что мне нужно взаимодействовать с данными из firebase в основном цикле (поэтому я не могу реализовать его в подписке или затем)

Это часть кода, которую я хочу создать:

        // Here i check if user exist in array (B)
        let IDUtente = RifEvento.esisteUtente(Ordini.IDUtente) ;

        // If not exists i'll get data from FIREBASE
        if (IDUtente == -1) {
           let NewUser = new TipoStatUtente() ;
           NewUser.Chiave = Ordini.IDUtente ;
           IDUtente = RifEvento.Utenti.push(NewUser) ;
           IDUtente = IDUtente - 1 ;

           // I NEED to wait the end of this function before continue with loop
           this.statoUtente.getUser(IDUtente).then(dati => {
              console.log('Sottoscritto dati utente') ;
              let user : TipoSingoloUtente = dati ;
              NewUser.sonoscuola = user.sonoscuola ;
              if (!NewUser.sonoscuola) NewUser.Intestazione = user.Cognome + ' ' + user.Nome ; else NewUser.Intestazione = user.Scuola.Nome ;
              if (NewUser.sonoscuola) RifEvento.NumScuole += 1 ; else RifEvento.NumUtenti += 1 ;
           })

        }

        console.log(IDUtente) ;

        // Utente Esiste aggiorno le sue statistiche
        RifEvento.Utenti[IDUtente].Commissioni  += Ordini.costoCommissione ;
        RifEvento.Utenti[IDUtente].Incasso      += Ordini.parziale ;
        if (Ordini.Tipo == 'T') {                  
           RifEvento.Utenti[IDUtente].NumTicket += Ordini.numbiglietti ;
         } else {
           RifEvento.Utenti[IDUtente].NumIscritti  += 1 ;
           RifEvento.Utenti[IDUtente].NumBallerini += Ordini.IDBallerini.length ;
          }



      }

А это функция:

getUser(IDUtente) : Promise<TipoSingoloUtente> {
return this.db.object('user/' + IDUtente).map(users => {
return users ;})
.first()
.toPromise(); }

person Riccardo Cassano    schedule 14.10.2017    source источник
comment
Является ли основной цикл циклом for?   -  person guest271314    schedule 14.10.2017
comment
Даже цикл синхронизирован, он не может блокироваться для асинхронного вызова. Таким образом, после вызова асинхронного вызова цикл продолжится. Вам нужно использовать функцию обратного вызова, чтобы контролировать конечный результат. (возможно, все обратные вызовы завершены, а затем возвращают окончательный результат)   -  person Xin Meng    schedule 14.10.2017
comment
Хорошо, дело в том, что цикл не заканчивается при асинхронном вызове... мне нужны данные асинхронного вызова для продолжения цикла... Есть ли способ заставить функцию ждать? (например, если у меня есть все данные в локальном массиве?)   -  person Riccardo Cassano    schedule 14.10.2017


Ответы (1)


Может быть, этот псевдокод может показать реализацию для поместить асинхронный вызов в цикл и убедиться, что все вызовы завершены, а затем что-то сделать.

global count = 0
loop A[i] i:0->A.size
    var B
    if(A[i] NOT IN B)
        async_function(A[i], callback(result))
    else
        //do something
        count++ 
    end if  
end loop A

callback(result)
    //do something
    count++
    if count == A.size 
        //all data has been processed
        //you also can only count the asyn calls
        //final report
    else
        //do nothing
end callback
person Xin Meng    schedule 14.10.2017
comment
проблема в том, что мне нужно продолжить основной цикл с данными асинхронного вызова... поэтому при обратном вызове мне нужно установить другой счетчик и принять решение о продолжении основного цикла... поэтому мне не нужно все время вызывайте асинхронную функцию... если у меня есть пользователь в основном цикле, я просто уточняю данные... - person Riccardo Cassano; 14.10.2017
comment
Я думаю, вам нужно переосмыслить это, вы не можете заблокировать основной цикл для асинхронного, поэтому вы не можете позволить основному циклу ждать вас асинхронным. Поэтому вам нужно думать, что это основано на асинхронном программировании без традиционного программирования. - person Xin Meng; 14.10.2017
comment
хорошо, значит, нет способа заставить основной цикл ждать (цепочку) ответа? - person Riccardo Cassano; 19.10.2017
comment
да, вы можете проверить этот stackoverflow.com/a/42173481/2000468, который объясняет цикл javascript - person Xin Meng; 20.10.2017