как оператор коммутатора отписался от предыдущих наблюдаемых? - PullRequest
2 голосов
/ 23 марта 2019

Я пытаюсь понять наблюдаемые. Когда я использовал оператор переключения, я не мог понять строку «он отменяет подписку на предыдущую наблюдаемую и подписывает новую»

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

Но когда я использую оператор переключения после оператора карты, выходные данные меняются на 1,2,3. Какой оператор коммутатора делает внутренне?

1 Ответ

1 голос
/ 23 марта 2019

Когда вы делаете t.map((e)=>Rx.Observable.range(1,3)), t сам по себе является Observable из входного события, и оттуда вы отображаете его в Observable из вложенного Observable, который будет излучать целые числа от 1 до 3.

Теперь вы применяете к нему оператор switch, который, по сути, действует на Observable of Observable. В вашем случае t.map(..) создает Observable для внутренней Observable, вызывая Rx.Observable.range(1,3) внутри нее.

Таким образом, как только Наблюдение будет отправлено из Rx.Observable.range(1,3), оператор коммутатора откажется от подписки на Наблюдение от вызова t.map(...) и подпишется на самую последнюю Наблюдаемую из вызова Rx.Observable.range(1,3).

Согласно документации оператора switch, обратите внимание на слово последний :

Switch подписывается на Observable, который испускает Observables. Каждый раз он наблюдает одну из этих излучаемых наблюдаемых, возвращаемая наблюдаемая Переключатель отписки от ранее выпущенного 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'>
...