1

Let's assume I'm uploading 100 images, so my Angular frontend has to make 100 API-calls. Yet due to backend restrictions, I would like to have a maximum of 5 simultaneous API requests at any given point of time. Whenever one of the http-requests in the queue is completed another request should be added and executed.

How can I achieve this?

kellermat
  • 2,859
  • 2
  • 4
  • 21
azby
  • 57
  • 4

2 Answers2

5

The second parameter of mergeMap corresponds to the maximum number of concurrent API calls. Setting this parameter to 5 means that at any given time, only 5 API requests will be executed, and as soon as one request finishes, another one will be initiated.

Check my Stackblitz example or have a look at the code below:

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.log(response);
  });
}

mockApiCall(value: number): Observable<number> {
  return of(value).pipe(delay(1000));
}
kellermat
  • 2,859
  • 2
  • 4
  • 21
0

You could use some of the rxjs operators to handle that.

The one I suggest is windowCount

import { fromEvent, windowCount, delay, skip, mergeAll } from 'rxjs';

uploads$.pipe(
  windowCount(3),
  delay(3000),
  concatMap((r)=>callYourApiHere(r))                 
);
// ....

And just use a uploads$ behaviour Subject to emit on every upload.

here is a better example

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.log("API CALLED")}),delay(2000)))
);
result.subscribe(x => console.log(x));

for(let i of [1,2,3,4,5,6,7,8,9]) {
  bh.next(i)
}
Caio Oliveira
  • 526
  • 4
  • 10