2016-12-20 6 views
1

RxJS: Как вы заключаете примитивный тип, такой как строки в и наблюдаемых слушать изменения в этом примитивном?RxJS: Как обернуть и наблюдать строку за изменения?

Рассмотрим следующий пример. setTimeout моделирует некоторое внешнее событие, которое меняет строку s. Однако console.log срабатывает только один раз, а не после того, как вызывается setTimeout. Почему это?

let s = "Hello World"; 
Observable.of(s).subscribe(val => { 
    console.log(val); 
}); 
// some external event changes variable s 
setTimeout(() => { 
    s = "Wat?"; 
}, 1000); 
// Output: prints "Hello World" to console, but not "Wat?" 

Этот вопрос может показаться немного тупым, но я искал в течение 2 часов через все виды RxJS документации и примеры, и большинство из них играет с массивами или объектами. Это не то, что я хочу. Я не хочу менять атрибуты, функции, массивы или что-то в этом роде. Просто простая строка или логическое значение или число.

+3

Струны неизменны. – Pointy

+0

Действительная точка. Итак, RxJS не учитывает это? – ntaso

+1

Ну, в вашем примере кода есть примитивная строка * значение * '" Hello World ", а затем есть * variable *' s'. Похоже, вы хотите, чтобы переменная была той, которую вы наблюдаете, и не столько строковое значение (что хорошо, потому что значение строки не изменится). – Pointy

ответ

2

Вы неправильно думаете о потоках. Вся суть потока состоит в том, что вы должны не быть мутировавшими объектами напрямую (строки не могут быть мутированы как уже упоминавшиеся @Pointy, но это более общая точка).

Вам нужно перевести свое мышление, чтобы данные были неизменными, а поток представлял изменение, на которое вы реагируете в подписчике.

В вашем примере, если вы хотите «мутировать» строку, то, что вы действительно пытаетесь сделать, это захватить набор изменений и обработать их через обработчик next метода subscribe. Там, где эти изменения происходят, не имеет никакого отношения к перспективе строки, она заботится только о том, что через нее проходят события.

то я мог бы сделать следующее испускать различные строки:

Rx.Observable.timer(1000) 
    .mapTo('Wat') 
    .startWith('Hello World!') 
    .subscribe(x => console.log(x)); 

Что вам нужно, чтобы определить, является то, что источником ваших изменений и какие события он должен излучать. Оттуда Rx может помочь вам массировать эти данные во что-то, что вы можете использовать вниз по течению.

+0

Спасибо за объяснение. Чтобы быть ясным: RxJS не имеет никакого отношения к устаревшему методу JS 'Object.observe()' vanilla и ничего, например, к наблюдаемым в Knockout или Angular 2 ?! Думаю, я думал о RxJS в качестве замены для этих более традиционных наблюдателей. В конце концов, RxJS назвал себя Lodash для Observables *, хотя они, по-видимому, удалили это из веб-сайта. – ntaso

1

Я понимаю, что этот вопрос имеет принятый ответ, но вот правильный способ наблюдения строки для изменений с помощью RxJS.

Создайте переменную типа ReplaySubject

stringVariable$: ReplaySubject<String> = new ReplaySubject<String>(); 

Присвоить все новые значения в stringVariable с помощью функции, чтобы поймать событие обновления.

assignNewValue(newValue: String) { 
    this.stringVariable$.next(newValue); 
} 

Подписаться на эту

наблюдаемых
stringVariable$.subscribe((newValue: String) => { 
    console.log(newValue); 
}); 

В качестве альтернативы вы можете использовать BehaviourSubject, если ваша переменная строка имеет начальное значение, чтобы начать с.

Смежные вопросы