Ожидание получения каждого ответа запроса
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),
});
}
}