Объединение нескольких наблюдаемых и действие, когда в Angular возвращается хотя бы одно значение - PullRequest
0 голосов
/ 13 марта 2019

У меня есть набор наблюдаемых, и мне нужно будет отреагировать, когда последний предоставит значение (в зависимости от того, какое из них будет).

Мой первый подход был forkJoin вот так.

const observables = [
  this.backend.config(),
  this.navigation.location()
];

forkJoin(observables)
  .subscribe(([backend, selection]) => {
    console.log(backend);
    console.log(selection);
  });

Это работало частично до тех пор, пока наблюдаемые издают в некоторой точке complete (после чего вызывается финализация. Затем я попытался ОбъединитьПоследний . Это решило исходная проблема, но создала новую. Теперь я получаю последний метод, вызываемый, как только любой из наблюдаемых обеспечивает.

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

Лучшее, но хакерское решение, которое я придумал, это проверить !! backend и !! navigation и действовать, только если все они удовлетворяют. Я ищу более плавное решение или подтверждение того, что то, что я использую, так же хорошо, как и получается.

combineLatest(observables)
  .subscribe(([a, b, c]) => {
    if (!a || !b || !c)
      console.log("Oh, I'm coming...");
    else
      console.log("Wham, bam - I'm done!");
  });

Все это из блогов вот так или , которые , публикуют сообщения на SO и Observables 'docs .

Ответы [ 2 ]

4 голосов
/ 13 марта 2019

Хорошо, вы опишите правильный оператор:

combineLatest не будет выдавать начальное значение, пока каждое наблюдаемое не испустит хотя бы одно значение

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

ref https://www.learnrxjs.io/operators/combination/combinelatest.html

1 голос
/ 15 марта 2019

Используйте zip вместо forkJoin. Он работает аналогично, но не требует наличия наблюдаемых для завершения.

const a$ = of('a');                       // will complete instantly
const b$ = timer(2000).pipe(mapTo('b'));  // will complete later 
const c$ = new BehaviorSubject('c');      // will never complete

zip(a$, b$, c$).subscribe(console.log)    // (after 2s) ['a', 'b', 'c']

демо: https://stackblitz.com/edit/rxjs-ycqqhn

...