Как сделать HTTP-вызовы внутри цикла и подождать, пока один завершится, прежде чем делать другой? - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть массив элементов, которые на каждом элементе я хочу сделать HTTP-вызов, дождаться его завершения, а затем сделать еще один вызов, только по одному за раз.

Я пытался:

index(item) {
   return this.service.index(item).pipe(
      map(response => {
         // handle success case
      }),
      catchError(error => {
         // handle error case
      })
   )
}

async processArray(array) {
  const promises = array.map(item => this.index(item));
  await Promise.all(promises);
}

proccessArray(array);

Также с эффектами NGRX:

@Effect()
effect$ = this.actions$.pipe(
   ofType<action>(actionTypes.action),
   mergeMapTo(this.store.select(getMyArray)),
   flatMap((request: any[]) => {
       return zip(...request.map(item => {  
         return this.service.index(item).pipe(
               map(response => {
                  // handle success case
               }),
               catchError(error => {
                  // handle error case
               })
            )
         }))
      }),
   );

Также пытался делать это в циклах for и forEach, но они запускают все запросы одновременно.Как мне этого добиться?

1 Ответ

0 голосов
/ 25 декабря 2018

Если вы используете обещания и хотите дождаться разрешения каждого обещания, прежде чем будет сделан другой вызов, то (1) вы не должны использовать Promise.all , так как это будет ждать, пока все запросы не будут решены и (2) вам нужно использовать обычный старый цикл for, который позволяет вам ожидать асинхронных операций в цикле.

async processArray(array) {
  for(var i = 0; i < array.length; i++){
    await yourServiceCall();
  }
}

В качестве идентификатора: поскольку вы используете async-await, не забудьте конвертируйте ваши наблюдаемые в обещания.

Если вы хотите отойти от обещаний (и async-await) и вместо этого полагаться на чистый RxJS, взгляните на concatMap :

Проецирует каждое исходное значение в Observable, которое объединяется в выходной Observable, в последовательном порядке, ожидая завершения каждого из них перед объединением следующего.

Дляпример:

import { from } from 'rxjs/observable/from';

ngOnInit() {
  from(myArray)
    .pipe(concatMap(el => yourServiceCall(el)))
    .subscribe(/* your logic */);
}
...