我有一个端点URL,例如http://site/api/myquery?start=&limit=,它返回一个字符串数组。 如果以这种方式调用此端点,则由于字符串长度很大,服务器将挂起。
我需要生成一个带有增量“开始”和“极限”参数的可观察对象数组,依次解析或并行解析所有元素,然后获得最终的可观察对象,最后观察得到一个真正的字符串数组,合并了内部Observables返回的所有字符串子数组。
我应该怎么做?
即可观察变量的数组就像
[
httpClient.get(http://site/api/myquery?start=0&limit=1000),
httpClient.get(http://site/api/myquery?start=1000&limit=1000),
httpClient.get(http://site/api/myquery?start=2000&limit=1000),
....
]
答案 0 :(得分:2)
如果在进行所有这些查询之前知道长度,那么您可以根据需要创建任意数量的http-get Observable,然后使用投影fn forkJoin
进行创建。
forkJoin
将使您进行并行查询,然后合并这些查询的结果。这是一个例子:
import { forkJoin } from 'rxjs';
// given we know the length:
const LENGTH = 500;
// we can pick arbitrary page size
const PAGE_SIZE = 50;
// calculate requests count
const requestsCount = Math.ceil(LENGTH / 50);
// generate calculated number of requests
const requests = (new Array(requestsCount))
.fill(void 0)
.map((_,i) => {
const start = i * PAGE_SIZE;
return http.get(`http://site/api/myquery?start=${start}&limit=${PAGE_SIZE}`);
});
forkJoin(
requests,
// projecting fn
// merge all arrays into one
// suboptimal merging, just for example
(...results) => results.reduce(((acc, curr)=> [...acc, ...curr]) , [])
).subscribe(array => {
console.log(array);
})
选中此forkJoin example以供参考。
希望这会有所帮助
答案 1 :(得分:1)
如果您不知道项目总数,则可以使用expand进行操作。
以下文章对expand
进行了很好的介绍,并解释了如何将其用于分页。
https://blog.angularindepth.com/rxjs-understanding-expand-a5f8b41a3602
在您的情况下,下面的代码行可能会起作用,因此需要依次请求每个页面。
const limit = 1000;
let currentStart = 0;
let getUrl = (start, limit) => `http://site/api/myquery?start=${start}&limit=${limit}`;
httpClient.get(getUrl(currentStart, limit)).pipe(
expand(itemsArray => {
if (itemsArray.length) {
currentStart += limit;
return httpClient.get(getUrl(currentStart, limit));
}
return empty();
}),
reduce((acc, value) => [...acc, ...value]),
).subscribe(itemsArray => {
console.log(itemsArray);
})
一旦解决了整个系列请求,这将注销最终的项目数组。