I have a list of objects and want to call a webservice for the first n objects. The api call returns the size of the object and I want to call until the total size sum reaches a threshold. My code so far:
const stop$: Subject<any> = new Subject();
this.totalFileSize = 0;
from(this.entities) // entities is an array of object with an id
.pipe(
mergeMap((e) =>
this.adminService.AdminTasksGetWebMetrics(e.id) // get the size of one object
),
takeUntil(stop$),
tap(result=>{
this.totalFileSize += result.Item.TotalSize;
if(this.totalFileSize>this.fGroup.get('BatchSize').value*1000000000){
stop$.complete();
}else{
stop$.next(1);
}
}),
...
Problem is that mergeMap will already send requests for all entities before the condition is checked. How would I achieve to test after each api call?
You could specify the concurrency parameter with mergeMap, limiting the number of active api calls:
from(this.entities).pipe(
mergeMap(e => this.adminService.AdminTasksGetWebMetrics(e.id), 3)
...
);
This would not completely prevent excessive calls, but could greatly limit them. You could, of course use concurrency = 1 (aka, concatMap
) which would eliminate excessive calls.
Also, instead of using a Subject
and keeping track of the total file size inside tap
, you could utilize the scan
operator, to keep track of the accumulated file size:
from(this.entities).pipe(
concatMap(e => this.adminService.AdminTasksGetWebMetrics(e.id)),
scan((total, size) => total + size, 0),
takeWhile(totalSize => totalSize < this.fGroup.get('BatchSize').value*1000000000)
);
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments