Слияние наблюдаемых и получение потока в одной подписке - PullRequest
1 голос
/ 17 октября 2019

У меня есть конечная точка, которая возвращает список избранных, затем, когда этот список возвращается, я получаю каждое из этих избранных и отправляю в другую конечную точку, чтобы получить конкретную информацию о каждом из этих избранных:

    this.favoriteData = [];
    const observables = [];
    favoriteList.forEach(favorite => {
      observables.push(this.assetService.getAsset(favorite.symbol)
        .pipe(takeWhile((response: AssetModel) => response.id !== 0)));
    });
    merge(...observables)
      .subscribe(res => {
        this.favoriteData.push(res);
        this.showLoading = false;
      });

Как видите, функция getAsset() вызывает конечную точку, и она находится внутри forEach, и я сохраняю каждый из этих ответов в массиве и распространяю этот массив в функции слияния RXJS, но когда я подписываюсь на объединенную наблюдаемуюи добавьте ответ к массиву favoriteData, поведение функции подписки будет таким, связывая по одному из данных ответа:

я хочуповедение, которое ждет, когда все запросы завершатся, а затем получит все ответы в одном потоке, я пытаюсь использовать оператор forkJoin, но tslint сообщает, что это устарело и использовать оператор карты, и я не знаю, как его использовать, чтобы сделатьчто я хочу

enter image description here

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Вы можете использовать from, чтобы сгенерировать Observable, который генерирует каждый элемент базового массива по одному. Затем, используя mergeMap и toArray, вы выводите все необходимые данные в конце:

const favoriteData$ = from(favoriteList).pipe(
  mergeMap(favorite => this.assetService.getAsset(favorite.symbol)
    .pipe(takeWhile((response: AssetModel) => response.id !== 0))),
  toArray()
);
0 голосов
/ 17 октября 2019

Вместо этого вы можете использовать combineLatest, который ожидает завершения всех наблюдаемых перед выпуском.

combineLatest(...observables)
  .subscribe(res => {
    this.favoriteData.push(res);
    this.showLoading = false;
  });
...