为每个订阅者评估的 rxjs 地图运算符
rxjs map operator evaluated for each subscriber
为什么地图运算符是针对每个订阅者而不是一次评估的?
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
我可以用不同的方式编写这个测试用例来避免这种行为吗?
每个订阅者都会 运行 通过 Observable 序列。如果您希望每个人都获得结果流,请使用 .publish().refCount()
.
http://jsbin.com/ditikonopi/edit?js,console
只要至少有一个订阅,.publish()
will return an observable sequence that shares a single subscription to the underlying sequence. refCount()
就会保持与来源的连接。
凯尔回答正确。 publish().refCount()
应用于所有三个 observable 将导致 map
选择器函数不会被重新执行。
为了更详细地说明该答案,了解使用 Rxjs 时冷热可观察对象之间的区别很有用。在你的例子中,你所有的可观察对象 obsX
都是冷的,所以它们是 'restarted' 订阅。 combineLatest
在幕后订阅了所有 3 个,这就是 map
被重新执行的原因。查看 以获得插图说明。对于初学者来说,这是一个常见的绊脚石,但它很容易理解。
为什么地图运算符是针对每个订阅者而不是一次评估的?
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
我可以用不同的方式编写这个测试用例来避免这种行为吗?
每个订阅者都会 运行 通过 Observable 序列。如果您希望每个人都获得结果流,请使用 .publish().refCount()
.
http://jsbin.com/ditikonopi/edit?js,console
只要至少有一个订阅,.publish()
will return an observable sequence that shares a single subscription to the underlying sequence. refCount()
就会保持与来源的连接。
凯尔回答正确。 publish().refCount()
应用于所有三个 observable 将导致 map
选择器函数不会被重新执行。
为了更详细地说明该答案,了解使用 Rxjs 时冷热可观察对象之间的区别很有用。在你的例子中,你所有的可观察对象 obsX
都是冷的,所以它们是 'restarted' 订阅。 combineLatest
在幕后订阅了所有 3 个,这就是 map
被重新执行的原因。查看