[英]RxJS, why does fromEvent() register a new event for each subscription?
假设我们有以下代码
const clickEvent$ = fromEvent(document, 'click').pipe(
pluck('target')
);
clickEvent$.pipe(
filter(node => node.id === 'button1')
).subscribe(() => {
console.log('Button 1 clicked!');
});
clickEvent$.pipe(
filter(node => node.id === 'button2')
).subscribe(() => {
console.log('Button 2 clicked!');
});
当我在调试器中查看已注册的事件时,我看到在文档上注册了两个单击事件。 当增加订阅次数为clickEvent$
,注册到文档的事件数也会随着每次订阅而增加。
相比之下,无论我添加到switch
语句的情况多少,下面的代码只会注册一个事件。
document.addEventListener('click', (event) => {
switch (event.target.id) {
case 'Button1':
console.log('Button 1 clicked!');
break;
case 'Button2':
console.log('Button 2 clicked!');
break;
}
});
所以我的问题是: -
以下是我对冷热观测资料的了解
share()
运算符可用于使冷可观察到热。 谢谢!
正如您可以通过单击run code snippet
看到的那样, 答案是肯定的 ,每次subscribe
click$
stream时都会附加侦听器。
每次订阅Observable时,事件处理函数都将在给定事件类型上注册到事件目标。 当该事件触发时,作为第一个参数传递给注册函数的值将由输出Observable发出。 取消订阅Observable时,将从事件目标取消注册该功能。
const { fromEvent } = rxjs; const { mapTo } = rxjs.operators; const target = document.getElementById('test'); /* ignore, debug */ const $delegate = target.addEventListener; target.addEventListener = (...args) => { console.log('registering listener'); return $delegate.apply(target, args); }; /* // */ const click$ = fromEvent(target, 'click'); click$.pipe( mapTo('stream 1: click'), ).subscribe(console.log); click$.pipe( mapTo('stream 2: click'), ).subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.js"></script> <button id="test">click here</button>
shared
流来避免这种情况。 const { fromEvent } = rxjs; const { mapTo, share } = rxjs.operators; const target = document.getElementById('test'); /* ignore, debug */ const $delegate = target.addEventListener; target.addEventListener = (...args) => { console.log('registering listener'); return $delegate.apply(target, args); }; /* // */ const click$ = fromEvent(target, 'click').pipe( share(), // <= share operator ); click$.pipe( mapTo('stream 1: click'), ).subscribe(console.log); click$.pipe( mapTo('stream 2: click'), ).subscribe(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.js"></script> <button id="test">click here</button>
正如您在上一个示例中所看到的,日志registering listener
器只发生一次。 有关the share operator
更多信息
希望能帮助到你!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.