论坛之类的网站通常会对发帖频率做限制,防止机器人刷屏的攻击。正好自己的项目要用到,所以就考虑了这个算法的实现。
实现原理:
- 创建一个队列,用于存放每次用户提交的内容和时间
- 用户提交
- 如果队列长度小于n,跳到5
- 如果当前时间 与 队列倒数第n个元素的创建时间之差大于m,跳到5,否则跳到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>
相关文档
随便看看
畅言模块加载中