例。
页面有一按钮,点击一次可以触发一个 Ajax 请求。如果不做特殊处理,那么,用户快速点击时就会触发大量 Ajax 请求,给服务器带来不必要的负担。
处理方法有多种:
点击后禁用按钮
代码如下 | 复制代码 |
//登录 function login(usernameId,pwdId,codeId){ suspendBtn(btnSubmit); $.ajax({ url: '/admin/WebService1.asmx/Login', type: 'POST', dataType:"xml", contentType :"application/x-www-form-urlencoded;charset=utf-8", data:{username:username.value,strPwd:pwd.value}, success: function(msg){ if(msg.text=="false"){ alert("请填写正确的用户名密码!"); username.select(); }else{ openWindow("default.aspx",true); } }, error: function(x, e) { alert(x.responseText); }}); resumeBtn(btnSubmit); } //挂起按钮 //恢复按钮 |
这是比较简单粗暴的方法,在用户第一次触发 click 事件后即禁用该按钮 – 设置 disabled 属性为 true。在处理完 Ajax 请求后,再根据情况决定是否启用该按钮。
Debounce
维基上 debounce 译成去除抖?印N颐强梢园延没а杆俚慊髟斐傻拇罅渴录?シ⒖闯伞感藕诺亩抖? – 这时触发事件处理器的信号处于不稳定状态。
debounce 方法的原理是,第一个事件触发时,对其绑定的事件函数做一定的延迟执行(setTimeout),比如100毫秒,如果100毫秒内没有再触发事件,则我们可以认为信息稳定,事件处理器将在预计的100毫秒【当然,这个时间并不准确,有兴趣可以看 JavaScript 异步一篇的说明】,但如果100毫秒内还在触发同一事件,则上一个延迟被清除(clearTimeout),新的延迟(setTimeout)替换进来。
于是,如果用户一直点击按钮并且两次点击的时间间隔小于100毫秒时,click 事件被持续触发,新的延迟不断替入旧的延迟,结果是事件处理器函数得不到执行。
举一个点击按钮提交 Ajax 请求的例子1:
代码如下 | 复制代码 |
$('#fav').on('click',function () { var timer = null; return function () { clearTimeout(timer);/每次执行时清除上一个延迟事件 timer = setTimeout(function () {//设定新延迟事件 $.ajax({...}); }, 100); } }); |
这个方法有一个明显的缺陷,就是用户正常点击时,事件的处理也被无例外地推迟100毫秒。
throttle
throttle的定义是:
a device controlling the flow of fuel or power to an engine.
在这里,可以简单理解成一个控制函数发生频率的机制2。
与 debounce 不同的是,throttle 方法不会延迟第一次事件的处理。它即时处理第一次事件,并记录时间,之后再发生事件,它再计算一个时间值,这个时间值表示,离第一次事件发生过去了多久,如果这个时间值小于设定的时间阀(threshold),则利用 setTimeout 推迟事件处理,一旦到达时间阀,则即时触发事件处理。
这样,throttle 就控制住密集事件可触发事件处理器的频率,比如每200秒(threshold)仅触发一个事件函数。具体应用请见扩展阅读3中 scroll 与 resize 事件的示例。