Это можно сделать в rxjs с помощью оператора expand
следующим образом:
import {HttpParams} from '@angular/common/http';
import {Observable, empty} from 'rxjs';
import {expand, map, reduce} from 'rxjs/operators';
export interface PostResponse {
posts: object[];
total: number;
}
@Injectable()
export class Service {
private readonly baseUrl = '...';
constructor(private http: HttpClient) {
}
getPosts(chunkSize: number): Observable<object[]>
{
let chunkOffset = 0;
return this.getPostsChunk({chunkOffset++, chunkSize}).pipe(
expand(({total}) => total >= chunkOffset * chunkSize
? getPostsChunk({chunkOffset++, chunkSize})
: empty()
),
map(res => res.posts),
// if you want the observable to emit 1 value everytime that
// a chunk is fetched, use `scan` instead of `reduce`
reduce((acc, val) => acc.concat(val), new Array<object>()),
);
}
getPostsChunk({chunkOffset, chunkSize}: {chunkOffset?:number, chunkSize:number})
{
const offset = (chunkOffset || 0) * chunkSize;
const limit = offset + chunkSize;
const params = new HttpParams({offset, limit});
return this.http.get<PostResponse>(this.baseUrl, {params});
}
}
Учитывая, что вы можете "рассчитать" количество запросов, необходимых для получения всех записей записей из итоговое значение, полученное после 1-го запроса, вы можете наиболее точно реализовать это другим способом, не используя оператор expand
.