Ожидание получения каждого ответа запроса

RxJS, Angular 9. Задача: в цикле нужно делать запрос для каждой item service.getData(item.param), дожидаться ответа и дальше итеарироваться по массиву.

Пример:

array.forEach(item => {
   if (!item.mark) {
      ожидание this.service.getData(item.type) // запрос на сервер
   }
});

Ответы (1 шт):

Автор решения: overthesanity

Это можно сделать с помощью RxJS, можно и с помощью обычных промисов + async/await.

Я предпочитаю второй вариант, более лаконичный + будет понятен всем участникам команды:

class SomeComponent {
  async iterateArrayAndMadeRequests() {
    const array = [
      {
        type: '1',
        mark: true,
      },
      {
        type: '2',
        mark: false,
      },
    ];

    for (const item of array.filter(item => !item.mark)) {
      // Я предполагаю, что `getData` возвращает
      // `return http.get(...)`
      await this.service.getData(item.type).toPromise();
    }
  }
}

Если не важна последовательность и все запросы могут быть параллельными:

class SomeComponent {
  async iterateArrayAndMadeRequests() {
    const array = [
      {
        type: '1',
        mark: true,
      },
      {
        type: '2',
        mark: false,
      },
    ];

    await Promise.all(
      array
        .filter(item => !item.mark)
        .map(item => this.service.getData(item.type).toPromise())
    );
  }
}

Если нужен RxJS (хотя зачем? ?):

class SomeComponent {
  iterateArrayAndMadeRequests() {
    const array = [
      {
        type: '1',
        mark: true,
      },
      {
        type: '2',
        mark: false,
      },
    ];

    from(array.filter(item => !item.mark))
      .pipe(concatMap(item => this.service.getData(item.type)))
      .subscribe({
        complete: () => console.log('Все запросы были сделаны '),
      });
  }
}

Если последовательность неважна, то mergeMap вместо concatMap.

Если нужно получить результаты всех запросов в виде массива:

class SomeComponent {
  iterateArrayAndMadeRequests() {
    const array = [
      {
        type: '1',
        mark: true,
      },
      {
        type: '2',
        mark: false,
      },
    ];

    forkJoin(
      array.filter(item => !item.mark).map(item => this.service.getData(item.type)),
    ).subscribe({
      next: results => console.log(results),
    });
  }
}
→ Ссылка