Javascript 反应式编程-值大于X并持续N秒
我有一个流Javascript 反应式编程-值大于X并持续N秒,javascript,reactive-programming,Javascript,Reactive Programming,我有一个流randStream,它每半秒发出一个随机值,boolStream将randStream中的值转换为布尔值 let randStream = Kefir.fromPoll(500, () => Math.random()) let boolStream = Kefir.map((rand) => rand > 0.5) 当boolStream连续发出true5秒时,我想发出true。否则emitfalse 我在用图书馆 你有什么想法吗?谢谢。对不起,我还不会写ES6
randStream
,它每半秒发出一个随机值,boolStream
将randStream
中的值转换为布尔值
let randStream = Kefir.fromPoll(500, () => Math.random())
let boolStream = Kefir.map((rand) => rand > 0.5)
当boolStream
连续发出true
5秒时,我想发出true
。否则emit
false
我在用图书馆
你有什么想法吗?谢谢。对不起,我还不会写ES6,但是。。。这个想法是,如果您的原始流每半秒采样一次,那么五秒的
true
是一行十一个true,对吗
// 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!");
});
编辑:我刚刚又读了一遍你的问题;如果您希望流是true
,如果您的最后5秒都是true
,则使用map
,而不是过滤器(和>=
而不是=
):
当您知道randStream
发出数字的确切速率时,在给定的条件下,使用很容易实现。滑动窗口
:
let result = boolStream
.slidingWindow(10, 10)
.map(items => _.every(items))
.skipDuplicates();
如果您希望它能够处理任意速率的事件,可以尝试以下方法:
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();
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();