什麼是防抖和節流?有什麼區別?如何實現?
1. 防抖
高頻率事件在n秒內只觸發一次,若是再次被觸發,則從新計時
設置定時器,當n秒內再次被觸發,則清除定時器。
<button id="btn">提交</button>
<script >
document.getElementById('btn').addEventListener('click', submit)
function submit(){
console.log('請求數據')
}
</script>
上面是最簡單的提交按鈕,如今的需求是點擊按鈕,請求後臺的數據。
若是按照上面的代碼,能夠實現,可是若是用戶連續點擊,就在形成資源浪費。這裏就用到了防抖。
document.getElementById('btn').addEventListener('click', debounce)
let timer = null
function debounce(){
clearTimeout(timer)
timer = setTimeout(function() {
submit()
}, 1000)
}
function submit(){
console.log('請求數據')
}
上面實現了最基本的 需求,如今有點很差,就是咱們定義了一個全局變量。基於儘量少的定義全局變量,咱們將
變量放入debounce 函數的內部
能夠作如下實現
document.getElementById('btn').addEventListener('click', debounce(submit))
function debounce(fn){
let timer = null
return function() {
clearTimeout(timer)
timer = setTimeout(function() {
fn()
}, 1000)
}
}
function submit(){
console.log('請求數據')
}
這裏是基於閉包實現的,按鈕element 監聽了 click事件,並執行debounce方法,debounce方法又返回一個新函數
,這裏的timer 就會一直存在,不被銷燬,由於函數被外部引用。
因此下次點擊的時候timer 仍是存在,咱們點擊的時候首先會clearTimeout,也就是取消上次的請求。
2.節流
高頻率事件在n秒內只觸發一次,n秒內再也不觸發。
仍是基於上面的例子
document.getElementById('btn').addEventListener('click', throttle)
let flag = true
function throttle(){
if (!flag) return
flag = false
setTimeout(function(){
submit()
flag = true
},1000)
}
function submit(){
console.log('請求數據')
}
上面定義了一個標記flag 表示當前函數執行狀態,若是以及過了1秒,請求數據執行後,咱們將flag設置成true,
說明函數可從新執行,不然就直接返回,不執行setTimeout,優化一下
document.getElementById('btn').addEventListener('click', throttle(submit))
function throttle(fn){
let flag = true
return function() {
if (!flag) return
flag = false
setTimeout(function(){
fn()
flag = true
},1000)
}
}
function submit(){
console.log('請求數據')
}