I have an array of subscriptions :
const partsArray = parts.map(item => this.partsService.deletePart(item.id));
Then I call a forkJoin on subscriptions and delete them all at once :
forkJoin(partsArray).subscribe({
error: (error: ApiError) => {
},
complete: () => {
}
});
The problem is that it could be 10 or 100, so I need to batch them and make a delay every 10.
10 API CALLS
Delay of 500ms
10 API calls
Delay of 500ms
How can I make it with rxjs ?
CodePudding user response:
If you have millions of parts, you can chunk the array ahead of time.
function chunk(arr, chunkSize) {
if (chunkSize <= 0) throw "Invalid chunk size";
let v = [];
for (let i=0,len=arr.length; i<len; i =chunkSize) {
v.push(arr.slice(i,i chunkSize));
}
return v;
}
const delayObs = timer(500).pipe(ignoreElements());
// An array of observables
const partsArray = parts.map(item => this.partsService.deletePart(item.id));
const partsChunked = chunk(partsArray, 10);
const apiResultsChunked = from(partsChunked).pipe(
concatMap(parts => concat(forkJoin(parts), delayObs))
);
apiResultsChunked.subscribe({
next: console.log,
error: (error: ApiError) => {
},
complete: () => {
}
});
You can simplify this a bit if you use RxJS buffer instead of pre-chunking your array.
from(
parts.map(item => this.partsService.deletePart(item.id))
).pipe(
bufferCount(10),
concatMap(parts => concat(
forkJoin(parts),
timer(500).pipe(ignoreElements())
))
).subscribe({
next: console.log,
error: (error: ApiError) => {},
complete: () => {}
});
CodePudding user response:
this may be what you are looking for.
const partsArray = parts.map(item => this.partsService.deletePart(item.id).pipe(delay(500)));
forkJoin(partsArray).subscribe(...)
check this documentation about RxJs: https://www.learnrxjs.io/learn-rxjs/operators/utility/delay