我有一个订阅事件监听器 Observable (fromEvent
) 的主题。单击按钮停止时,主题完成,事件监听器应被删除。目前,我正在跟踪订阅并取消订阅,这也会删除事件监听器:
const { fromEvent, Subject } = rxjs
const { map } = rxjs.operators
const subject = new Subject()
subject.subscribe(() => console.log('focused'))
const sub = fromEvent(document.querySelector('input'), 'focus').subscribe(subject)
document.querySelector('button').onclick = () => {
// This is what I would like to avoid
sub.unsubscribe;
subject.complete();
}
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
<input>
<button>Stop</button>
是否可以在 subject
完成时自动取消订阅订阅 sub
(并删除事件监听器)?类似 takeUntilComplete(subject)
的东西,无需安装额外的库。
编辑:这里的例子过于简单了。在我的真实场景中,没有让主题完成的按钮。
最佳答案
你想多了,这就是你所需要的:
const stop$ = fromEvent(document.querySelector('button'), 'click');
fromEvent(document.querySelector('input'), 'focus').pipe(takeUntil(stop$)).subscribe(subject)
takeUntil
的完成将向下传播到订阅的主题。所有订阅和事件监听器都将以单击按钮结束。
唯一不会发生的事情是,如果主题以某种方式完成,而不是单击按钮,那么您的输入事件仍将触发,尽管订阅者将不再收听。完成传播到下游但不传播到上游。
或者创建新的运算符非常简单(重复您的解决方案):
const takeUntilComplete = (subject) =>
takeUntil(new Observable(o =>
subject.subscribe(null, null, () => o.next())))
可以简单地用作:
fromEvent(document.querySelector('input'), 'focus').pipe(takeUntilComplete(subject)).subscribe(subject)
关于javascript - 订阅主题完成后退订,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63940583/