Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/grails/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js baconjs:使用条件限制连续事件_Node.js_Reactive Programming_Bacon.js - Fatal编程技术网

Node.js baconjs:使用条件限制连续事件

Node.js baconjs:使用条件限制连续事件,node.js,reactive-programming,bacon.js,Node.js,Reactive Programming,Bacon.js,我正在用Node.js编写一个消息应用程序,我需要检测同一用户何时在一个组中发送N条连续消息(以避免垃圾邮件发送者)。我正在使用一个总线,其中我推送来自所有用户的传入消息 消息如下所示: { "text": "My message", "user": { "id": 1, name: "Pep" } } 这是迄今为止我的工作代码: const Bacon = require('baconjs') const bus = new Bacon.Bus(); const CONSECUTI

我正在用Node.js编写一个消息应用程序,我需要检测同一用户何时在一个组中发送N条连续消息(以避免垃圾邮件发送者)。我正在使用一个
总线
,其中我
推送来自所有用户的传入消息

消息如下所示:

{
  "text": "My message",
  "user": { "id": 1, name: "Pep" }
}
这是迄今为止我的工作代码:

const Bacon = require('baconjs')
const bus = new Bacon.Bus();

const CONSECUTIVE_MESSAGES = 5;

bus.slidingWindow(CONSECUTIVE_MESSAGES)
   .filter((messages) => {
       return messages.length === MAX_CONSECUTIVE_MESSAGES &&
              _.uniqBy(messages, 'user.id').length === 1;
    })
   .onValue((messages) => {
       console.log(`User ${__.last(messages).user.id}`);
   });

// ... on every message
bus.push(message);
它创建了一个滑动窗口,只保留我想要检测的连续消息的数量。在每个事件中,它都会过滤数组,以便仅当窗口中的所有消息都属于同一用户时,数据才会流向下一步。最后,在
onValue
中,需要最后一条消息来获取用户id

在我看来,代码相当脏/复杂:

  • 过滤器
    在流中看起来不太自然。当N个连续事件符合某些条件时,是否有更好的方法来发出事件
  • onValue
    功能中,是否有更好的方法让用户只接收单个事件(而不是一系列消息)
  • 它并不是真正的节流阀。如果一个用户在一年内发送N条消息,则不应检测到他或她。溪流应该以某种方式忘记过去的事件
  • 有什么改进的办法吗?如果有帮助的话,我愿意将其迁移到rxjs。

    也许可以从

    latestMsgsP = bus.slidingWindow(CONSECUTIVE_MESSAGES)
      .map(msgs => msgs.filter(msg => msgAge(msg) < AGE_LIMIT))
    
    你可以用一些无耻的命令,比如

    
    函数getUserToBlock(msgs){
    if(msgs.length<连续_消息)返回
    让用户识别;
    对于(变量i=0;i

    考虑尽早映射您感兴趣的属性,这样流的其余部分就更简单了。此外,滑动窗口中每个项目的相等性检查不会随着阈值的增加而很好地扩展。考虑使用<代码>扫描< /COD>,因此只需保留当前和先前值不匹配时重置的计数。

    总线
    .map(“.user.id”)
    .扫描([0],([n,a],b)=>[a==b?n+1:1,b])
    .filter(([n])=>n>=最大连续消息数)
    .onValue(([count,userId])=>void console.log(`User${userId}`);
    
    let blockedUserIdP = latestMsgsP.map(getUserToBlock)