我有一个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();


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

最佳答案

问题是.onValue(f)向事件流注册了一个订阅者,并且由于您的流已经在示例中进行了缓冲并准备就绪(因为您使用了fromArray()),因此该流立即被分派给新的订阅者并被使用结束。如果尝试设置combined流并首先对其调用.log(),则会导致相同的问题。

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


  创建一个EventStream来传递给定的一系列值(给定
  作为数组)到第一个订户。这些值之后,流结束
  已交付。


实际上,如果您的事件流来自连续/随机的事件(例如用户输入或点击事件),则您的代码通常可以在事件真正发生之前根据需要设置具有所需订阅者或子流数量的流,像这样:

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

关于javascript - 如何派生/复制流,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27661570/

10-09 10:12