为每个订户评估rxjs map运算符

kas*_*ask 6 javascript rxjs

为什么为每个订户评估地图运营商而不是一次?

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)
});
Run Code Online (Sandbox Code Playgroud)

我在这里创建了一个测试用例:http://jsbin.com/jubinuf/3/edit?js,console

我可以用不同的方式编写此测试用例以避免此行为吗?

Kyl*_*ley 6

每个订阅者都将运行Observable序列.如果您希望每个人都获得结果流,请使用.publish().refCount().

http://jsbin.com/ditikonopi/edit?js,console

.publish()会返回共享一个单一订阅的基本序列可观察序列.refCount()只要至少有一个订阅,它将保持与源的连接.


use*_*222 4

凯尔的回答是正确的。publish().refCount()应用于所有三个可观察量将导致map选择器函数不被重新执行。

为了更详细地阐述这个答案,在使用 Rxjs 时了解热可观察值和冷可观察值之间的区别是很有用的。就您而言,您的所有可观察量obsX都是冷的,因此它们在订阅时“重新启动”。combineLatest在后台订阅了所有 3 个,这就是map重新执行的原因。看看这里的图解解释。对于初学者来说这是一个常见的障碍,但它很容易理解。