2014-12-26 1 views
1

У меня есть поток 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

Вопрос заключается в том, что .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(); 
+0

Вы также можете превратить свой примерный поток в async с помощью простого '.delay (0)' – OlliM