如何分叉/复制流

时间:2014-12-26 20:19:53

标签: javascript ruby-on-rails node.js bacon.js

我有outer个流。我想以两种不同的方式使用此流。 第一种方法是只听取价值观。 第二种方法是使用flatMapConcat构建新流。

但我不能同时做到这两件事。我想我必须分叉或复制流。

我尝试过添加总线,但它不起作用。

var outer = Bacon.fromArray([1, 2, 3, 4, 5]);


// 1.way build a new stream
var combined = outer.flatMapConcat(function(v) {
  return Bacon.sequentially(1000, ["a" + v, "b" + v]);
});


// 2. way use the plain stream
// outer.onValue(function(v) { console.log(v); });

// Tried to insert a bus
var forkBus = new Bacon.Bus();

forkBus.plug(outer);

forkBus.onValue(function(v) {
console.log('outer side' + v);
});

combined.take(3).log();

如何分叉/复制流,以便以两种不同的方式使用它?

1 个答案:

答案 0 :(得分:1)

问题是.onValue(f)将订阅者注册到事件流,并且因为您的流已经在示例中缓冲并准备就绪(因为您使用了fromArray()),所以流会立即被分派到新用户并被消费到最后。如果您尝试设置combined流并首先在其上调用.log(),则会出现同样的问题。

Bacon.fromArray()的文档提示:

  

创建一个EventStream,它传递给定的一系列值(给定   as array)到第一个订阅者。在这些值之后,流结束   已经交付。

实际上,如果您的事件流来自连续/随机(如用户输入或点击事件),您的代码通常可以根据需要设置具有尽可能多的订阅者或子流的流在任何事件发生之前,如下:

var outer = $('#some-number-input').asEventStream('input')...;

outer.onValue(function(v) { console.log(v); });

var combined = outer.flatMapConcat(function(v) {
    return Bacon.sequentially(1000, ["a" + v, "b" + v]);
});

combined.take(3).log();

// After this point, any event that occurs in `outer` will pass
// through both functions

如果您想对流进行某些操作而不进行修改(并且没有注册将使用该流的订阅者),您可以使用doAction

var outer = Bacon.fromArray([1, 2, 3, 4, 5]);

var actioned = outer.doAction(function(v) {
    console.log(v);
});

var combined = actioned.flatMapConcat(function(v) {
    return Bacon.sequentially(1000, ["a" + v, "b" + v]);
});

combined.take(3).log();