Я хочу отказаться от подписки в декларативном стиле с помощью оператора «takeUntil». Но это в принципе не работает. Я все равно вижу вывод консоли.
const unsubscribe = new Subject();
function printFoo() {
of('foo')
.pipe(takeUntil(unsubscribe))
.subscribe(console.info) // Why I can see 'foo' in the console?
}
function onDestroy() {
unsubscribe.next();
unsubscribe.complete();
}
onDestroy()
setTimeout(() => printFoo(), 200)
StaackBlitz:
https://stackblitz.com/edit/rxjs-svfkxg?file=index.ts
P.S. Я ожидал, что даже unsubscribe.next() будет достаточно, чтобы отписаться, но даже с unsubscribe.complete() не получается.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы звоните onDestroy() еще до того, как цепочка с takeUntil создана.
Когда вы в конце концов позвоните printFoo(), предыдущие выбросы в unsubscribe не будут повторно отправлены, а Тема unsubscribe в любом случае уже завершена, поэтому takeUntil в этом случае никогда не завершит цепочку.
Потому что Субъект излучает до printFoo подписки.
После подписки выпусков Subject больше не будет.
Вместо этого вы можете использовать BehaviorSubject, так как он содержит испускаемые значения (последний испускаемое значение):
const unsubscribe = new BehaviorSubject(false);
function printFoo() {
of('foo')
.pipe(takeUntil(unsubscribe.pipe(filter(value => !!value)))) // Don't unsub if it's false emitted
.subscribe(console.info)
}
function onDestroy() {
unsubscribe2.next(true); // Emit true to cancel subscription
}