azby
azby

Reputation: 67

How to limit the number of simultaneous http requests, using Angular?

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?

Upvotes: 2

Views: 1574

Answers (2)

kellermat
kellermat

Reputation: 4515

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));
}

Upvotes: 6

Caio Oliveira
Caio Oliveira

Reputation: 804

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)
}

Upvotes: 0

Related Questions