今天和別人聊到JavaScript函數的節流和防抖,發現自己對這兩個的區別很是模糊,遂小小實踐一下,在此記錄,希望對需要的人有所幫助。
節流 - 頻繁操作,間隔一定時間去做一件事
舉例說明:假定時間間隔為 500ms,頻繁不停的操作 2s,且每兩次執行時間小于等于時間間隔 500ms,那么就會執行 4 次,也就是每隔 時間間隔 500ms 執行一次。
防抖 - 頻繁操作,一定時間間隔內只執行最后一次操作
舉例說明:假定時間間隔是 500ms,頻繁不停的操作 5s,且每兩次執行時間小于等于時間間隔 500ms,那么最后只執行了 1 次,也就是每一次執行時都結束了上一次的執行。
代碼示例
//節流方法 1function throttle1(method, duration){var prevTime = new Date();return function () {var context = this,currentTime = new Date(),resTime = currentTime - prevTime;//打印出本次調用方法和上次執行方法的時間差console.log("時間差"+resTime);//當本次調用距離上次執行方法的時間差大于等于要求時間間隔時,執行一次方法if(resTime >= duration){method.apply(context);//記錄執行方法的時間prevTime = currentTime;}}}//節流方法 2function throttle2(method, duration){//當前時間間隔內是否有方法在執行(或者說方法的調用是否在進行)var runningFlag = false;return function (e) {// 判斷當前是否有方法在執行,有,則什么都不做if (runningFlag) {return false;}//開始執行runningFlag = true;setTimeout(function(){method(e);//執行完畢,聲明當前沒有正在執行的方法,方便下一個時間間隔內的調用runningFlag = false;}, duration)}}//防抖function debounce(method, duration){var timer = null;return function(){var context = this,args = arguments;//在本次調用之前的一個間隔時間內,有方法在執行,則終止該方法的執行if(timer){clearTimeout(timer);}//開始執行本次調用timer = setTimeout(function(){method.apply(context, args);},duration);}}//模擬三個執行方法function jieliu1(){console.log("節流 1");}function jieliu2(){console.log("節流 2");}function fangdou(){console.log("防抖");}//持續執行時間var totalTime = 2000;var jieliuFn1 = throttle1(jieliu1,500);var jieliuFn2 = throttle2(jieliu2,500);var fangdouFn = debounce(fangdou,500);(function(duration){setInterval(function(){if( totalTime > 0 ){jieliuFn1();jieliuFn2();fangdouFn();totalTime -= duration;}},duration);})(100);
運行結果
時間差 100
時間差 201
時間差 303
時間差 401
時間差 504
節流 1
時間差 98
節流 2
時間差 199
時間差 300
時間差 396
時間差 496
時間差 597
節流 1
時間差 100
節流 2
時間差 203
時間差 299
時間差 402
時間差 500
節流 1
時間差 103
時間差 204
節流 2
時間差 303
時間差 400
節流 2
防抖
結論
由以上運行結果可以看出,節流1 出現了 3 次,節流2 出現了 4 次,防抖出現了 1 次。防抖實現順利,但是兩個節流方法的執行結果存在差異。
觀察時間差可以看出,每次節流1 執行時,時間差并不會都是 500 整,也就是說,一共調用 2 秒時,節流1 并不能做到每隔 500 毫秒執行一次而共執行 4 次,第四次執行往往因為前面的 3 次執行的時間誤差,而導致到達時間 2 秒時,最后一次的時間差無法達到 時間間隔 500ms 以上,以至于只能執行 3 次。
結論:當在一個大范圍的時間內,比如兩小時內,每幾分鐘執行一次,超過2小時則不再實行,推薦使用第一種節流方式,;如果僅僅要求間隔一定時間執行一次,推薦使用第二種節流方法;防止頻繁操作,比如表單多次提交,推薦使用防抖。