Объединение нескольких HTTP-запросов в Angular
В статье мы рассмотрим метод отправки нескольких параллельных HTTP запросов в Angular, используя Observable.forkJoin.
Допустим, у нас есть 2 конечных точки API, которые предоставляют 2 разных набора данных. Мы хотим создать список в нашем приложении, используя оба набора данных.
getVehicles(): Observable< any > {
const cars = this.http.get(CARS_ENDPOINT).map(res => res.json());
const bikes = this.http.get(BIKES_ENDPOINT).map(res => res.json());
}Мы можем использовать RxJS forkJoin, чтобы объединить ответы от двух запросов:
import { forkJoin, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(
private httpClient: httpClient,
) { }
getVehicles(): Observable< any > {
return forkJoin(
this.httpClient.get(CARS_ENDPOINT),
this.httpClient.get(BIKES_ENDPOINT)
).pipe(
tap(response => {
// responses[0] => cars
// responses[1] => bikes
})
);
}
}Заметить, что:
- Переменная response, которую мы получаем из Observable.forkJoin, представляет собой массив из 2 элементов - столько же, сколько элементов в массиве, который мы передаем forkJoin.
- Порядок значений в ответах также совпадает с порядком параметров.
- Оба запроса выполняются параллельно, но массив ответов отправляется, когда все запросы получают данные от своих конечных точек, то есть он должен ждать завершения всех запросов, а затем мы получаем значение массива ответов.
Разбирать массив не очень удобно, очередность может изменится и под индексом 0 могут оказаться другие данные, для того чтобы быть уверенными в том что вы используете нужные данные можно воспользоваться оператором tap и подписаться на изменения в самом запросе а не в forkJoin, как в примере ниже:
import { forkJoin, Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(
private httpClient: httpClient,
) { }
getVehicles(): Observable< any > {
return forkJoin(
this.httpClient.get(CARS_ENDPOINT).pipe(
tap(response => this.cars = response)
),
this.httpClient.get(BIKES_ENDPOINT).pipe(
tap(response => this.bikes = response)
)
);
}
}Обратите внимание, чтобы отправить запросы у forkJoin необходимо вызвать метод subscribe