为什么要为每个订户评估地图运营商而不是一次?
const obs1 = Rx.Observable.interval(1000).take(1).map((x, i) => {
console.log(i+1 + ':1 map')
return 'obs1';
})
const obs2 = Rx.Observable.interval(1300).take(1).map((x, i) => {
console.log(i+1 + ':2 map')
return 'obs2';
})
const obs3 = Rx.Observable.interval(1700).take(2).map((x, i) => {
console.log(i+1 + ':3 map')
return 'obs3';
})
const view = obs1.combineLatest(obs2, obs3, (obs1, obs2, obs3) => { return obs1 + ', ' + obs2 + ', ' + obs3; });
// Every subscriber adds more calls to map - why is it called multiple times at the same time ?
view.subscribe((value) => {
console.log('sub1: ' + value)
});
view.subscribe((value) => {
console.log('sub2: ' + value)
});
view.subscribe((value) => {
console.log('sub3: ' + value)
});
我在这里创建了一个测试用例:http://jsbin.com/jubinuf/3/edit?js,console
我能否以不同的方式编写此测试用例以避免此行为?
答案 0 :(得分:6)
每个订阅者都将运行Observable序列。如果您希望每个人都获得结果流,请使用.publish().refCount()
。
http://jsbin.com/ditikonopi/edit?js,console
.publish()
将返回一个可观察序列,该序列共享对基础序列的单个订阅。只要至少有一个订阅,refCount()
就会与源保持联系。
答案 1 :(得分:4)
凯尔的回答是正确的。 publish().refCount()
应用于所有三个observable将导致map
选择器函数无法重新执行。
要详细说明该答案,了解使用Rxjs时热和冷可观察量之间的区别很有用。在您的情况下,您的所有可观察量obsX
都很冷,因此在订阅时会重新启动它们。 combineLatest
在所有3个版本下订阅,这就是重新执行map
的原因。请查看here以获得图解说明。对于初学者来说,这是一个常见的绊脚石,但它很容易理解。