RxJS:如何包装和观察字符串的变化?

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。这不是我想要的。我不想更改属性,函数,数组或类似的东西。只是一个简单的字符串或布尔值或数字。

pau*_*els 5

您正在错误地考虑流。流的重点是你应该直接改变对象(字符串实际上不能像@Pointy 已经提到的那样改变,但这是一个更一般的观点)。

您需要将您的想法转变为将数据视为不可变的,并将流视为代表您对订阅者做出反应的变化。

在您的示例中,如果您想“改变”一个字符串,您真正想要做的是捕获一组更改并通过方法的next处理程序显示它们subscribe。从字符串的角度来看,这些更改来自哪里无关紧要,它只关心正在通过它传递的事件。

即我可以执行以下操作来发出不同的字符串:

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

您需要确定的是更改的来源是什么以及它应该发出什么事件。从那里 Rx 可以帮助您将这些数据转化为可以在下游使用的东西。


Gri*_*mer 5

我确实意识到这个问题有一个公认的答案,但这里是使用 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