Окончательный ответ на этот вопрос
Правильный ответ на этот вопрос дает следующий пост .
Мой первый ответ - упрощенный c ответ
То, что вы видите, зависит от того, что ваш код является полностью синхронным, и, следовательно, unsubscribe
после 3 излучений, что подразумевается в take(3)
, не имеет возможности бежать.
Посмотрите на эту версию
of(null, 20, 15, 10, 5, 6, 9)
.pipe(
delay(0), // >>> intruduce a delay
tap(val => console.log(`Tapped value ${val}`)),
filterNil(),
take(3)
)
Здесь вы вводите delay
, который дает take
возможность unsubscribe
, и, как следствие, вы видите поведение, которое вы ожидайте.
Не ответ, а более подробное обоснование
Я немного больше изучил эту проблему и обнаружил некоторые вещи, которые делают мой предыдущий ответ немного слишком просто.
Начнем с того, что filterNil()
является законным пользовательским оператором, который должен делать то же самое, что и filter(item => item !== null)
, где filter
является оператором, предоставленным rxjs/operators
, то есть библиотекой .
Теперь, если мы заменим filter(item => item !== null)
на filterNil()
в pipe
, мы получим другой результат
of(null, 20, 15, 10, 5, 6, 9)
.pipe(
tap(val => console.log(`Tapped value ${val}`)),
filter(item => item !== null),
take(3)
)
.subscribe(
item => console.log(`Rendering Item ${item}`),
err => console.log(err),
() => console.log('Completed')
);
}
// the output on the console is
Tapped value null
Tapped value 20
Rendering Item 20
Tapped value 15
Rendering Item 15
Tapped value 10
Rendering Item 10
Completed
Это означает, что filter(item => item !== null)
и filterNil()
не эквивалентно.
Тот факт, что они не эквивалентны, по-видимому, является следствием реализации subscribe
метода соединения Observable
с несколько иной природой filterNil
и filter
.
При использовании filterNil
, след выполнения subscribe
мето d of Observable это
Если, с другой стороны, мы используем оператор filter
, трассировка выполнения метода subscribe
Наблюдается это
Следовательно, тот факт, что filterNil
имеет атрибут operator
, установленный на ноль, в то время как filter
имеет атрибут operator
, установленный на FilterOperator
похоже, ведет другое поведение. Причины этого мне не ясны и стоят нового вопроса.