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

时间:2016-01-21 19:46:26

标签: 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)
});

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

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

2 个答案:

答案 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以获得图解说明。对于初学者来说,这是一个常见的绊脚石,但它很容易理解。