解析可观察对象数组并追加到最终数组中

时间:2019-04-12 10:29:50

标签: rxjs

我有一个端点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),
    ....
]

2 个答案:

答案 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); 
})

一旦解决了整个系列请求,这将注销最终的项目数组。