javascript - 订阅主题完成后退订

标签 javascript typescript rxjs

我有一个订阅事件监听器 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/

相关文章:

javascript - 在 JavaScript 中嵌入 HTML

javascript - 获取具有相同类的元素的 id

reactjs - 使用 Material UI makeStyles 时输入的 props

javascript - 在 ngIf 之后获取父元素的子元素(Angular 5)

javascript - Angular 2 AsynPipe 不与 Observable 一起工作

javascript - 如何更改元素 "B"onFocus 元素 "A"的类名

javascript - 表格搜索框

javascript - 避免在 TypeScript 中生成 `f(...args: any[])` 的死代码

javascript - RxJS 订阅者取消订阅与完成

javascript - 为什么我们需要返回一个流而不是直接调度一个值?