Предположим, я загружаю 100 изображений, поэтому мой интерфейс Angular должен сделать 100 вызовов API. Тем не менее, из-за внутренних ограничений я хотел бы иметь максимум 5 одновременных запросов API в любой момент времени. Всякий раз, когда один из http-запросов в очереди завершается, должен быть добавлен и выполнен другой запрос.
Как я могу этого добиться?
Вы можете использовать некоторые из операторов rxjs, чтобы справиться с этим.
Я предлагаю windowCount
import { fromEvent, windowCount, delay, skip, mergeAll } из 'rxjs';
uploads$.pipe(
windowCount(3),
delay(3000),
concatMap((r)=>callYourApiHere(r))
);
// ....
И просто используйте тему поведения uploads$ для отправки при каждой загрузке.
вот лучший пример
import { fromEvent, windowCount, delay, skip, mergeAll,of, switchMap, Subject, tap, concatMap } from 'rxjs';
const bh = new Subject()
const result = bh.pipe(
windowCount(3),
concatMap((a)=>of(new Date().getSeconds()).pipe(tap(()=>{console.info("API CALLED")}),delay(2000)))
);
result.subscribe(x => console.info(x));
for(let i of [1,2,3,4,5,6,7,8,9]) {
bh.next(i)
}
Второй параметр mergeMap
соответствует максимальному количеству одновременных вызовов API. Установка этого параметра на 5 означает, что в любой момент времени будет выполняться только 5 запросов API, и как только один запрос завершится, будет инициирован другой.
Посмотрите мой пример Stackblitz или взгляните на код ниже:
import { mergeMap, of } from 'rxjs';
// Set max. number of simultaneous requests:
const numberOfSimultaneousRequests = 5;
// Add 50 observables that will execute the API-requests:
const allApiCalls = Array.from({ length: 50 }, (_, i) => this.makeApiCall(i));
of(...allApiCalls)
.pipe(mergeMap((apiCall) => apiCall, numberOfSimultaneousRequests))
.subscribe((response) => {
console.info(response);
});
}
mockApiCall(value: number): Observable<number> {
return of(value).pipe(delay(1000));
}