nta*_*aso 6 javascript primitive-types observable rxjs typescript
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?"
Run Code Online (Sandbox Code Playgroud)
这个问题听起来可能有些愚蠢,但是我搜索了2个小时的各种RxJS文档和示例,其中大多数使用Arrays或Objects。这不是我想要的。我不想更改属性,函数,数组或类似的东西。只是一个简单的字符串或布尔值或数字。
您正在错误地考虑流。流的重点是你不应该直接改变对象(字符串实际上不能像@Pointy 已经提到的那样改变,但这是一个更一般的观点)。
您需要将您的想法转变为将数据视为不可变的,并将流视为代表您对订阅者做出反应的变化。
在您的示例中,如果您想“改变”一个字符串,您真正想要做的是捕获一组更改并通过方法的next处理程序显示它们subscribe。从字符串的角度来看,这些更改来自哪里无关紧要,它只关心正在通过它传递的事件。
即我可以执行以下操作来发出不同的字符串:
Rx.Observable.timer(1000)
.mapTo('Wat')
.startWith('Hello World!')
.subscribe(x => console.log(x));
Run Code Online (Sandbox Code Playgroud)
您需要确定的是更改的来源是什么以及它应该发出什么事件。从那里 Rx 可以帮助您将这些数据转化为可以在下游使用的东西。
我确实意识到这个问题有一个公认的答案,但这里是使用 RxJS 观察字符串更改的正确方法。
为ReplaySubject类型创建一个变量
stringVariable$: ReplaySubject<String> = new ReplaySubject<String>();
Run Code Online (Sandbox Code Playgroud)
stringVariable通过函数将所有新值分配给以捕获更新事件。
assignNewValue(newValue: String) {
this.stringVariable$.next(newValue);
}
Run Code Online (Sandbox Code Playgroud)
订阅这个 Observable
stringVariable$.subscribe((newValue: String) => {
console.log(newValue);
});
Run Code Online (Sandbox Code Playgroud)
或者,如果您的字符串变量有一个初始值,您可以使用BehaviourSubject。