Подождите, пока не завершится неизвестное количество наблюдаемых - PullRequest
0 голосов
/ 25 января 2019

Есть довольно много вопросов подобного характера, я думаю, что это немного по-другому.

Рассмотрим следующий код:

arr = [];

this.service1.getItem()
  .subscribe(item => {
    Object.entries(item).forEach(([key, value]) => {
    if (some_condition_true) {
      this.service2.getSomeItems2(value.prop1).pipe(first())
        .subscribe(result => value.xyz = result);
        this.arr.push(value);
    }
 });

});

// This line should execute only after the 'forEach' above completes
this.someService.someMethod(arr);

Проблема в том, что я не знаю заранее, сколько раз будет звонить service2.getSomeItems2.

Кроме того, zip и forkJoin принимают Observables, но я уже подписался. Может быть, я могу tap вместо subscribe '. Но факт остается неизвестным о количестве наблюдаемых.

Ответы [ 2 ]

0 голосов
/ 26 января 2019

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

Хитрость здесь в том, чтобы сопоставить (используя mergeMap или switchMap) от вашегопервый запрос к объединенному выводу (используя forkJoin) ваших множественных вторых запросов.

Я думаю, это должно выглядеть так:

this.service1.getItem()
  .pipe(
    mergeMap(item => forkJoin(getItemRequests(item)))
  ).subscribe(arr => this.someService.someMethod(arr));

getItemRequests(item: any): Observable<any>[] {
  return Object.entries(item)
    .filter(([key, value]) => some_condition_true)
    .map(([key, value]) => this.service2.getSomeItems2(value.prop1)
      .pipe(
        first(),
        tap(result => value.xyz = result),
        map(result => value)
      )
    );
}
0 голосов
/ 26 января 2019

Как насчет этого?

this.service1.getItem()
  .pipe(switchMap(items => {
      const itemReqs = Object.entries(items)
                       .filter(v => some_condition_true_or_false)
                       .map(item => this.service2.getSomeItems2(item.prop1).pipe(first()));

     return forkJoin(itemReqs);

  }))
  .subscribe(data_from_service_2_calls => {
     data_from_service_2_calls.forEach(v => console.log(v))
   });

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

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

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