ex - I'm uploading 100 images, and UI is making calls for 100 times. Due to backend restrictions, I would like to have only 5 API calls to the max at any given point of time. UI should be adding another call as soon as 1 call in the queue gets completed.
How can I maintain queue?
Thanks
CodePudding user response:
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));
}
CodePudding user response:
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)
}