如何分叉/复制一个stream

我有一个外stream。 我想用两种不同的方式使用这个stream。 第一种方法是只听价值观。 第二种方法是用flatMapConcatbuild立一个新的stream。

但我不能同时做两个。 我想我必须叉或复制stream。

我尝试添加一个总线,但它不工作。

 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(); 

我如何分叉/复制一个stream,所以我可以用两种不同的方式使用它?

问题在于.onValue(f)注册了一个订阅者到事件stream,并且因为你的stream已经在你的示例中被caching并准备好了(因为你使用了fromArray() ),所以stream立即被分派给新的订阅者并被消费到最后。 如果您尝试设置combinedstream并在其上调用.log() ,则会导致相同的问题。

Bacon.fromArray()的文档暗示了这一点:

创build一个EventStream,将给定的一系列值(以数组forms给出) 传递给第一个用户 。 在这些值被传递后,stream结束

事实上,如果您的事件stream来自连续/随机(如用户input或点击事件),您的代码通常能够在任何事件实际发生之前根据需要设置具有尽可能多的用户或子stream的stream,像这样:

 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 

如果你想对stream进行一些操作而不修改它(也没有注册一个订阅者,这会消耗stream),你可以使用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();