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

RxJS: How to wrap and observe string for changes?

RxJS:如何将原始类型(例如 string 包装在 Observable 中并 listen 更改那个原始人?

考虑以下示例。 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 文档和示例,其中大部分都使用数组或对象。这不是我想要的。我不想更改属性、函数、数组或类似的东西。只是一个普通的字符串或布尔值或数字。

您对流的理解有误。流的全部要点是你应该 而不是 直接改变对象(字符串实际上不能像@Pointy 已经提到的那样改变,但这是一个更一般的观点)。

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

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

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

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

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

我知道这个问题有一个公认的答案,但这是使用 RxJS 观察字符串变化的正确方法。

创建类型为 ReplaySubject

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

通过捕获更新事件的函数将所有新值分配给 stringVariable

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

订阅这个 Observable

stringVariable$.subscribe((newValue: String) => {
    console.log(newValue);
});

或者,如果您的字符串变量有初始值,您可以使用 BehaviourSubject