我正在尝试学习Rxjs,我看到了一些我没想到的行为。有问题的javascript代码列在下面
function updateText(css_link, observable){
observable.subscribe(x => {
const container = document.querySelector(css_link);
container.textContent = `${x}`;
});
}
function log(observable) {
observable.subscribe(i => {
console.log(i);
});
}
let source = Rx.Observable.timer(0, 1000)
.map(() => {return {value: Math.random()}});
let double = source
.map(x => {return {value: x.value * 2}});
let diff = source
.pairwise()
.map(a => JSON.stringify(a));
updateText("#source", source.map(x => x.value));
updateText("#double", source.map(x => x.value));
updateText("#diff", diff);
事实证明double
流的输出是新随机数的双倍值,而不是来自source
的随机数。在查看diff
的输出时,我再次得到随机数在source
,double
和diff
中独立生成的印象。
我正在学习Rxjs,我可能会错过一点。我认为这些流是不可改变的,但它们确实依赖于彼此。
您可以在jsbin上找到此代码的一个版本,其中一些html会更新。
答案 0 :(得分:2)
这是因为您每次订阅时都会使用新的源Observable创建新链。这意味着source
,double
和diff
每个人都有自己的计时器。
每次创建新计时器时,您都可以通过向控制台打印消息来确定这一点:
let source = Rx.Observable.defer(() => {
console.log('new source');
return Rx.Observable.timer(0, 1000)
.map(() => {return {value: Math.random()}});
});
现在,您将在控制台中看到三条消息"new source"
。
如果您想共享单个源Observable,您可以使用多播,特别是share()
运算符。
let source = Rx.Observable.defer(() => {
console.log('new source');
return Rx.Observable.timer(0, 1000)
.map(() => {return {value: Math.random()}});
}).share();
现在,您只能在控制台中看到一个"new source"
,它应该可以正常运行。
所以您的来源可能如下所示:
let source = Rx.Observable.timer(0, 1000)
.map(() => {return {value: Math.random()}})
.share();