Разрешить массив наблюдаемых и добавить в окончательный массив - PullRequest
2 голосов
/ 12 апреля 2019

У меня есть URL-адрес конечной точки, например http://site/api/myquery?start=&limit=, который возвращает массив строк.Если я называю эту конечную точку таким образом, сервер зависает, так как массив длин строк огромен.

Мне нужно сгенерировать массив наблюдаемых с инкрементными параметрами "start" и "limit", разрешить все из них либо последовательно, либо параллельно, а затем получить окончательную наблюдаемую, которая в конце дает истинное значение.массив строк, полученный путем слияния всех подмассивов строк, возвращаемых внутренними наблюдаемыми.

Как мне это сделать?

то есть массив наблюдаемых будет выглядеть примерно так:

[
    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 ]

2 голосов
/ 12 апреля 2019

Если вы знаете длину до выполнения всех этих запросов - тогда вы можете создать столько http-get Observables, сколько вам нужно, а затем forkJoin их, используя проекцию fn.

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 для справки.

Надеюсь, это поможет

1 голос
/ 12 апреля 2019

В случае, если вы не знаете общее количество предметов, вы можете сделать это, используя , разверните .

. Следующая статья дает хорошее введение в 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); 
})

Выполняется выход из окончательного массива элементов после разрешения всей серии запросов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...