2015-05-12 10 views
7

Mam strumień randStream, który emituje losową wartość co pół sekundy i boolStream, który przekształca wartość z randStream na wartość logiczną.Programowanie reaktywne - wartość jest większa niż X dla N sekund

let randStream = Kefir.fromPoll(500,() => Math.random()) 
let boolStream = Kefir.map((rand) => rand > 0.5) 

że chce emitują true gdy boolStream emituje true do 5 sekundach (w rzędzie). W przeciwnym razie emit false.

Używam biblioteki Kefir.js.

Czy masz jakieś pomysły? Dzięki.

Odpowiedz

1

Z podanych warunkach, gdy wiesz dokładnie tempo, w jakim randStream emitują cyfry, to całkiem łatwe do osiągnięcia z .slidingWindow:

let result = boolStream 
    .slidingWindow(10, 10) 
    .map(items => _.every(items)) 
    .skipDuplicates(); 

Jeśli chcesz go do pracy z dowolnym tempie wydarzeń, można spróbować coś takiego:

let result = boolStream 
    .scan(({mostRecentFalse, latestValue}, bool) => { 
    return bool ? 
     {mostRecentFalse, latestValue: true} : 
     {mostRecentFalse: Date.now(), lastValue: false} 
    }, {mostRecentFalse: Date.now()}) 
    .changes() 
    .map(({mostRecentFalse, latestValue}) => 
    latestValue && (Date.now() - mostRecentFalse > 5000)) 
    .skipDuplicates(); 
1

Niestety, nie mogę napisać jeszcze ES6, ale ... chodzi o to, że jeśli twój pierwotny strumień jest próbkowany raz na pół sekundy, pięć sekund true jest jedenaście razy z rzędu, prawda?

// generate random numbers 
var randStream = Kefir.fromPoll(500, function() { 
    return Math.random(); 
}); 

// make into booleans 
var boolStream = randStream.map(function(rand) { 
    return rand > 0.5; 
}); 

// count trues in a row 
var trueStreakStream = boolStream.scan(function(numTrue, curr) { 
    return curr ? numTrue + 1 : 0; 
}, 0); 

// see when there's exactly 11 of them 
var elevenTruesStream = trueStreakStream.filter(function(numTrue) { 
    return numTrue == 11; 
}); 

// react 
elevenTruesStream.onValue(function(numTrue) { 
    console.log("five seconds of true!"); 
}); 

EDYCJA: Właśnie przeczytałem twoje pytanie znowu; jeśli chcesz strumień, który będzie true jeśli wszystkie ostatnich 5 sekundach były true, a następnie użyć map zamiast filter (i >= zamiast ==):

var lastElevenAreTrueStream = trueStreakStream.map(function(numTrue) { 
    return numTrue >= 11; 
}); 
Powiązane problemy