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