javascript - 切换操作员如何取消订阅以前的 observables?
问题描述
我试图理解可观察的。当我使用 switch 运算符时,我无法理解“它取消订阅以前的 observable 并订阅新的”这一行
var inp=document.getElementById("i");
var t=Rx.Observable.fromEvent(inp,"keyup");
t.map((e)=>Rx.Observable.range(1,3)).subscribe((e)=>console.log(e))
///t.map((e)=>Rx.Observable.range(1,3)).switch().subscribe((e)=>console.log(e))
每当我在输入框中按任意键时,我都会在没有切换运算符的情况下获得此输出:
RangeObservable {start: 1, rangeCount: 3, scheduler: CurrentThreadScheduler}
rangeCount: 3
scheduler: CurrentThreadScheduler {}
start: 1
__proto__: ObservableBase
但是当我在 map 运算符之后使用 switch 运算符时,输出变为1,2,3
. switch 操作员在内部做什么?
解决方案
当你在做的时候t.map((e)=>Rx.Observable.range(1,3))
,t
它本身就是一个来自输入事件的 Observable,然后你将它映射到一个嵌套的 Observable 的Observable,它会发出从 1 到 3 的整数。
现在你switch
在它上面应用操作符,它本质上作用于 Observable 的 Observable。在您的情况下,t.map(..)
是通过在内部调用来创建内部 Observable 的 Observable Rx.Observable.range(1,3)
。
因此,一旦从Rx.Observable.range(1,3)
switch 操作符发出 Observable,就会从t.map(...)
调用中取消订阅 Observable 并订阅调用的最新 Observable Rx.Observable.range(1,3)
。
根据运营商的文档,switch
请注意单词latest:
Switch 订阅了一个发出 Observables 的 Observable。每次它观察到其中一个发出的 Observable 时,Switch 返回的 Observable 都会取消订阅先前发出的 Observable,开始从最新的Observable 发出项目。
要将您的代码更改为不使用,您需要从调用switch
中订阅嵌套的 Observable :t.map(...)
t.map((e)=>Rx.Observable.range(1,3)).subscribe((e)=> e.subscribe(e => console.log(e)))
这将1, 2, 3
在控制台中输出。所以switch
让它更优雅,而不是订阅嵌套的 Observable,你只需在它发出后立即切换到它。
t.map((e)=>Rx.Observable.range(1,3)).switch().subscribe((e)=>console.log(e))
// ^
// |_________________ now this Observable is subscribed as soon as it is emitted.
这是一个演示如何订阅内部 Observable 以在没有 1、2、3 的情况下获得switch
:
var inp=document.getElementById("input");
var t=Rx.Observable.fromEvent(inp,"keyup");
console.log("** Without Switch ***")
t.map((e)=>Rx.Observable.range(1,3)).subscribe((e)=> e.subscribe(e => console.log(e)));
<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.6/dist/global/Rx.umd.js"></script>
Enter something: <input type="text" id='input'>
这与以下内容相同switch
:
var inp=document.getElementById("input");
var t=Rx.Observable.fromEvent(inp,"keyup");
console.log("** With Switch ***")
t.map((e)=>Rx.Observable.range(1,3)).switch().subscribe(e=> console.log(e));
<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.6/dist/global/Rx.umd.js"></script>
Enter something: <input type="text" id='input'>
推荐阅读
- excel - 循环变成无穷大并导致excel崩溃
- html - HTML 页眉和页脚:从一处编辑多个文件
- python - Scrapy将链接的请求合并为一个
- php - 如何使用 FPDF PHP 代码直接显示打印页面?
- angular - angular 6子路由组件未加载?
- asterisk - 星号中单个调用的多个唯一标识
- javascript - 无法在生产网络上卷曲网站,只能在 localhost - php 中工作
- css - 为什么1em不是基于定义的16px?
- python-sphinx - 如何使用 sphinx 分配案例的标签中心?
- python - IOError: ('http 错误', 403, 'Forbidden',
)