javascript - switch operator 如何取消订阅之前的 observables?

标签 javascript asynchronous rxjs reactive-programming

我正在尝试理解可观察对象。 当我使用 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 运算符(operator)在内部做什么?

最佳答案

当你在做 t.map((e)=>Rx.Observable.range(1,3)) 时,t 本身就是一个来自输入的 Observable事件并从那里将其映射到 嵌套 Observable 的 Observable,它将发出 1 到 3 之间的整数。

现在您在其上应用 switch 运算符,它实际上作用于 Observable 的 Observable。在你的例子中,t.map(..) 通过在内部调用 Rx.Observable.range(1,3) 创建一个内部 Observable 的 Observable。 p>

因此,一旦从 Rx.Observable.range(1,3) 发射了一个 Observable,switch 运算符就会取消订阅来自 t.map(...)< 的 Observable/code> 调用并订阅 Rx.Observable.range(1,3) 调用的最新 Observable。

根据 documentation switch 运算符,请注意单词latest:

Switch subscribes to an Observable that emits Observables. Each time it observes one of these emitted Observables, the Observable returned by Switch unsubscribes from the previously-emitted Observable begins emitting items from the latest Observable.

要将代码更改为不使用 switch,您需要从 t.map(...) 调用订阅嵌套的 Observable:

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 以在没有 switch 的情况下获得 1、2、3:

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'>

关于javascript - switch operator 如何取消订阅之前的 observables?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55310798/

相关文章:

javascript - 为什么我下载这个 Plnkr 后不起作用?

javascript - Angular JS 深度链接将刷新 View

c# - 如何等待异步调用完成?

javascript - 如果我只使用一个运算符,我应该使用管道运算符吗?

javascript - 使命名的 anchor 书签在单击时始终显示在屏幕顶部

javascript - 在 R shiny 中加载页面时调用 javascript 函数

javascript - JS链的 promise 和结果总是得到解决

c# - 如何异步执行同步方法并等待结果

angular - 如何使用可观察对象在 Angular2 中进行嵌套服务调用?

angular - 从 Angular 4 应用程序向 Paypal Payflow API 发布请求时,在控制台日志中出现 Access-Control-Allow-Origin 错误