Приведен ли порядок наблюдаемых для объединения последних релевантных?

У меня есть две наблюдаемые, которые я хочу объединить с combineLatest:

const o1 = from(['a', 'b', 'c']);
const o2 = of('content from o2');
combineLatest(o1, o2)
  .subscribe(result => console.log(result));

Как я понял combineLatest, когда выдает любой наблюдаемый объект, он объединяет последние значения всех наблюдаемых и генерирует их:

Когда какой-либо наблюдаемый излучает значение, испускает последнее значение из каждого. (https://www.learnrxjs.io/operators/combination/combinelatest.html)

Однако с приведенным выше кодом вывод будет следующим:

["c", "content from o2"]

Таким образом, только когда o2 излучает, combineLatest излучает значение.

Если я переключу порядок передачи o1 и o2, он будет работать должным образом:

const o1 = from(['a', 'b', 'c']);
const o2 = of('content from o2');
combineLatest(o2, o1)
  .subscribe(result => console.log(result));

Выход:

["content from o2", "a"]
["content from o2", "b"]
["content from o2", "c"]

Это ожидаемое поведение? Если да, то почему? Это, кажется, противоречит определению ob combineLatest.


person fjc    schedule 03.08.2018    source источник
comment
staltz.com/primer-on-rxjs-schedulers.html   -  person cartant    schedule 05.08.2018


Ответы (2)


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

В вашем первом случае o1 испускает все значения до того, как o2 испускает свое значение. Во втором случае o2 сначала выдает свое значение, а затем o1 излучает все свои значения. В реальных примерах у вас есть естественная задержка наблюдаемых значений (вызовы служб и т. Д.), Поэтому обычно порядок не имеет значения.

person René Winkler    schedule 03.08.2018

Я не могу не подчеркнуть, насколько полезным я нашел combineLatestObject из rxjs -etc, автор - @cartant.

Вы предоставляете объекту именованные наблюдаемые объекты, а затем вместо возврата массива получаете объект с именованными значениями.

combineLatestObject({

   isRaining: this.isRaining$,
   isSnowing: this.isSnowing$

}).pipe(map(({ isSnowing, isRaining }) => {

   return (isSnowing ? "It's snowing " : "It isn't snowing ") + "and " +
          (isRaining ? "it's raining " : "it isn't raining");

});

Внутри map() или switchMap() вы можете деконструировать объект, как я сделал здесь, или просто предоставить единственный параметр, в котором вы можете получить доступ к значениям map(data => data.isSnowing).

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

Почему это не часть основной библиотеки, я не знаю!

person Simon_Weaver    schedule 01.09.2019
comment
Красиво, но вы также можете разобрать его таким образом: combineLatest(this.isRaining$, this.isSnowing$).pipe(map([isRaining, isSnowing]) => {...}); - person pasevin; 31.08.2020