RxJS filter () непредвиденное поведение - PullRequest
1 голос
/ 20 июня 2019

Я сталкивался либо с этим странным поведением, либо с чем-то, чего я еще не знаю.Для следующего:

of(1).pipe(
  filter(_ => false),
  startWith('hello')
).susbcribe(val => console.log(val));

Вышеприведенный код выводит на консоль hello.

Я ожидаю, что фильтр позволит только успешным условиям идти по цепочке операторов, какдавай он сможет выводить привет через startWith ()?Это ожидаемое поведение?

Ответы [ 2 ]

2 голосов
/ 20 июня 2019

startWith происходит после того, как вы отфильтровали свое содержимое.

of(1).pipe(           // will yield (1)
  filter(_ => false), // will yield ()
  startWith('hello')  // will yield ('hello')
).susbcribe(val => console.log(val));

Итак, поток, состоящий из 1, отфильтрован, чтобы ничего не пропустить вещь сама по себе .Затем эта вещь «украшается» оператором startWith, что дает ей начальный hello.

Этот новый поток - тот, на который вы подписаны!

Это действительно предназначено

Пусть startWith будет выше filter в аргументах pipe(...), и вы увидите, как это изменится:

of(1).pipe(           // will yield (1)
  startWith('hello'), // will yield ('hello', 1)
  filter(_ => false)  // will yield ()
).susbcribe(val => console.log(val));

Для решения проблем вВ разделе комментариев вы можете представить цепочку pipe как nested calls.Например, в псевдокоде:

A.pipe(B, C, D)

... эквивалентно выполнению:

D(C(B(A)))

Таким образом, следующее:

of(1).pipe(           // expression A
  filter(_ => false), // expression B
  startWith('hello')  // expression C
).susbcribe(val => console.log(val));

..будет переводиться в:

startWith(         // expression C
    filter(        // expression B
        of(1),     // expression A
        _ => false
    ),
    'hello'
).susbcribe(val => console.log(val))

Или, более "императивным" способом:

const one = of(1);
const filtered = filter(one, _ => false);
const greeted = startWith(filtered, 'hello');
greeted.subscribe(val => console.log(val));

Тогда становится ясно, что фильтр может не влиять на операторовдальше по цепочке!

0 голосов
/ 21 июня 2019

Оператор startWith () просто вызывает оператор concat () .С аргументом начала в качестве первой наблюдаемой и внешней наблюдаемой в качестве второй.

https://github.com/ReactiveX/rxjs/blob/40a2209636a8b4d4884f5d59ad206ae458ad2de4/src/internal/operators/startWith.ts#L68

Оператор concat() генерирует значения для каждой наблюдаемой в последовательности от left *От 1012 * до вправо .Наблюдаемая первая должна выдать все значения и завершиться до того, как будет выпущена наблюдаемая следующая .

Например;

   concat(of('a','b'), of('1', '2')
      .subscribe(val => console.log(val));
   // prints 'a', 'b', '1', '2'

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

   concat(of('hello'), of(1).pipe(filter(_ => false))
      .subscribe(val => console.log(val));
   // prints "hello"

Итак startWith() переупорядочивает последовательность наблюдаемых такчто значение испускается первым, но, поскольку он является оператором, он может только поднять внешней наблюдаемой.Любые операторы, помещенные в pipe() после startWith(), будут применены к наблюдаемой, которая является результатом вызова concat().

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