展开目录
m秒内最多n次的问题
javascript
X
陈尼玛的博客
记录开发生涯的踩坑经历,用时间来验证成长
加载中

论坛之类的网站通常会对发帖频率做限制,防止机器人刷屏的攻击。正好自己的项目要用到,所以就考虑了这个算法的实现。

实现原理:

  1. 创建一个队列,用于存放每次用户提交的内容和时间
  2. 用户提交
  3. 如果队列长度小于n,跳到5
  4. 如果当前时间队列倒数第n个元素的创建时间之差大于m,跳到5,否则跳到6
  5. 本次提交结果和时间添加进队列,清除队列中多余的元素,跳到7
  6. 操作失败,跳到7
  7. 等待用户下一次操作,跳到2

以下是js实现的一个实例。

<meta charset='utf-8' />
<table>
  <td>剩余时间: </td><td id='c'>0</td><tr/>
  <td>消息: </td><td id='m'>-</td><tr/>
</table>
<input type='button' id='a' value='添加' />
<script type="text/javascript">

var timequeue=function(totaltime,count){
  var q=[];
  /* 加入队列接口
   * 允许加入的条件是以下两者之一:
   * 1. 队列有效长度小于count
   * 2. 队列倒数第count个元素的创建时间与当前时间之差大于totaltime
   */
  this.join=function(o,success,fail){
    try{
      if(q.length<count)throw 0;
      var z=new Date-q[q.length-count].c;
      if(z>totaltime)throw 0;
      fail(totaltime-z);
    }catch(e){
      q.push({o:o,c:new Date});
      q.splice(0,q.length-count);
      success();
    }
  };
  /*
   * 调试接口,生产环境中不需要
   */
  this.debug={
    q:q,
    totaltime:totaltime,
    count:count
  };
};

var t=new timequeue(9*1000,6);

a.onclick=function(){
  t.join(1,function(){
    m.innerHTML='<font color="green">成功</font>';
  },function(n){
    m.innerHTML='<font color="red">失败,距离下次还需要'+(n/1000|0)+'秒</font>';
  });
};

setInterval(function(){
  var n=[],d=t.debug,i;
  d.q.map(function(a){
    if(new Date-a.c<d.totaltime)
      n.push((d.totaltime-(new Date-a.c))/1000|0);
  });
  i=n.length;
  while(n.length<d.count)
    n.push('-');
  c.innerHTML=n.join(' ');
  t.innerHTML=i>d.count-1?'距离下次还需要'+Math.ceil((
    d.totaltime-(new Date-t.debug.q[t.debug.q.length-6].c)
  )/1000)+'秒':'-';
},16);

</script>

相关文档

  1. 判断变量是否 0 或者 '0'

  2. replace2正则扩展方法

  3. 简易版事件封装

  4. youku电脑版跳过广告代码

  5. 解密某个js文件

  6. 破解百度云下载链接

  7. 让js支持带命名的正则表达式

  8. jshtml模板引擎

  9. json2html源码

  10. 读取Blob的内容实体

  11. 判断一个object是否HTMLDom

  12. 简易命令行解析器

  13. Promise才是javascript的正统队列

  14. callback => Promise.then

  15. nodejs异步回调的并发控制

  16. 低版本IE命名函数表达式bug

  17. 让重复调用只有第一次生效

  18. 简易JSON函数封装

  19. 使用eval来修改上下文的变量

  20. seajs同步加载依赖的实现和弊病

  21. html5页面全屏方法

  22. 给滚动条置顶添加过渡动画

  23. 让代码扁平化

  24. 关于自动加载的问题

随便看看

  1. git 大小写不区分问题

  2. 定长消息队列读写优化

  3. mac ssh透过代理连接

  4. sass变量和继承类写法

  5. raw.githubusercontent.com DNS被指向127.0.0.1

  6. 搜索命令整理

  7. heroku登陆cli

  8. npm设置仓库地址和代理

  9. dd备份/还原

  10. 树莓派配置wifi热点

  11. git 设置代理服务器

  12. ssl 证书生成方式

  13. 把树莓派的存储空间拓展到整张TF卡中

  14. centos查看最近一次的开机时间

  15. mysql导出csv文件

  16. mysql选取内容导出到文件

  17. 简易版事件封装

  18. 配置mysql ssl连接

  19. html表格导出csv文件并下载

畅言模块加载中