RxJS:如何在 Observable 中包装原始类型(如字符串),如何监听对该原语的更改?
考虑以下示例。 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?"
这个问题可能听起来有点愚蠢,但我通过各种RxJS文档和示例搜索了2个小时,其中大多数都使用数组或对象。这不是我想要的。我不想更改属性,函数,数组或类似的东西。只是一个普通的字符串或布尔或数字。
答案 0 :(得分:3)
我确实知道这个问题有一个公认的答案,但这是使用RxJS观察字符串变换的正确方法。
创建变量stringVariable$: ReplaySubject<String> = new ReplaySubject<String>();
通过函数将所有新值分配给stringVariable
以捕获更新事件。
assignNewValue(newValue: String) {
this.stringVariable$.next(newValue);
}
订阅此Observable
stringVariable$.subscribe((newValue: String) => {
console.log(newValue);
});
如果你的字符串变量有一个初始值,你可以使用BehaviourSubject。
答案 1 :(得分:2)
您正在考虑错误的流。流的重点是你应该不直接变异对象(字符串实际上可以像@Pointy已经提到的那样被变异,但这是一个更普遍的观点)。
您需要转变您的想法,将数据视为不可变,并将流视为表示您对订阅者做出反应的更改。
在你的例子中,如果你想&#34;变异&#34;一个字符串,你真正想要做的是捕获一组更改并通过next
方法的subscribe
处理程序表示它们。这些变化来自于字符串的观点,它只关心事件是通过它传递的。
即。我可以执行以下操作来发出不同的字符串:
Rx.Observable.timer(1000)
.mapTo('Wat')
.startWith('Hello World!')
.subscribe(x => console.log(x));
您需要确定的是您的更改的来源以及应该发出的事件。从那里,Rx可以帮助您将这些数据按到您可以在下游使用的东西。