主题。消息监听器示例

时间:2016-03-22 21:21:14

标签: system.reactive reactive-programming rxjs

我需要创建一系列消息。

  • 我应该能够按顺序“推送”消息
  • 我应该能够“查询”所有消息
  • 我应该能够通过新消息通知所有听众。

现在我完成了:

var math = require('mathjs')
var Rx = require('rx')
var _ = require('lodash')

var messagesSubject = new Rx.Subject()
var messagesPool = messagesSubject.map(function() { return [el]}).scan([], _.union)


Rx.Observable
  .interval(500 /* ms */)
  .timeInterval()

  .filter(
    function() { return math.randomInt(10) > 8;}
  )
  .do(function(x) {
    messagesSubject.subscribe(function(msg) {
      console.log('subscriber ' + x.value + ' do something with ' + msg.text)
    })
  }).subscribe()

Rx.Observable
  .interval(500 /* ms */)
  .timeInterval()
  .filter(
    function() { return math.randomInt(10) > 2;}
  )
  .map(function() {
    return { text: math.pickRandom(['one', 'two', 'three'])}
  }).subscribe(messagesSubject)

如何通过以前的所有消息(messagesPool)通知每个新订阅者?

附带问题:主题的有效用例是否有效?或者我应该选择其他类型的主题?

3 个答案:

答案 0 :(得分:2)

听起来你正在寻找ReplaySubject而不是Subject

  

[ReplaySubject是一个]主题,它缓冲它观察到的所有项目并将它们重放到任何订阅的观察者。

答案 1 :(得分:1)

正如其他人所指出的那样,ReplaySubject可以成为你的朋友。

这可能意味着您可以删除邮件池功能。

如果你只是撰写查询,你也可以完全摆脱这个主题:

var math = require('mathjs')
var Rx = require('rx')
var _ = require('lodash')

var messages = Rx.Observable
  .interval(500 /* ms */)
  .timeInterval()
  .filter(
    function() { return math.randomInt(10) > 2;}
  )
  .map(function() {
    return { text: math.pickRandom(['one', 'two', 'three'])}
  })
  .replay();

//Randomly add subscribers (but this would only be dummy code, not suitable for prod)
var randomSubsriberAdder = Rx.Observable
  .interval(500 /* ms */)
  .timeInterval()
  .filter(
    function() { return math.randomInt(10) > 8;}
  )
  .subscribe(function(x) {
    messages.subscribe(function(msg) {
      console.log('subscriber ' + x.value + ' do something with ' + msg.text);

var connection = messages.Connect();
//messages will now be collecting all values.
//  Late subscribers will get all previous values.
//  As new values are published, existing subscribers will get the new value.

使用硬编码数据集和Rx测试工具/库可能会更好。 通过这种方式,您可以控制正在测试的边缘情况(早期用户,延迟用户,断开用户,流上的静音等等。)

答案 2 :(得分:1)

不使用主题的代码示例,使用重放语义和临时订阅者进行单元测试。使用[1,2,3,4].map(x => x+1); // ==> [2,3,4,5]

在节点上运行

(windows cmds)

node-unit

npm install rx npm install node-unit .\node_modules\.bin\nodeunit.cmd tests 目录中的代码。

test