在事件被觸發 n 秒後再執行回調,若是在這 n 秒內又被觸發,則從新計時。javascript
好比有一個關鍵詞搜索的input框,用戶輸入後觸發keyup事件向後端發送一個請求:html
<div>
<input id="input" type="text">
</div>
<script> const input = document.getElementById('input') input.addEventListener('keyup', (e) => { console.log(e.target.value) }) </script>
複製代碼
測試後能夠發現,每次輸入都會有打印結果,若是是請求後端接口,那麼不只會形成極大的浪費,並且實際應用中,用戶也是輸出完整的字符後,纔會請求。下面咱們優化一下:java
function debounce(fn, delay) {
let timer = null
return function(...args) {
const context = this
if(timer) {
clearTimeout(timer)
}
const _agrs = args.join(',')
timer = setTimeout(fn.bind(context, _agrs), delay)
}
}
const consoleDebounce = debounce(console.log, 500)
const input = document.getElementById('input')
input.addEventListener('keyup', (e) => {
consoleDebounce(e.target.value)
})
複製代碼
在運行一次後能夠看到,當在頻繁的輸入時,並不會打印結果,只有當你在指定間隔內沒有輸入時,纔會執行函數。若是中止輸入可是在指定間隔內又輸入,會從新觸發計時。git
function debounce(fn, delay = 500, immediate = false) {
let timer = null
return function(...args) {
const context = this
// 是否當即執行一次
if (immediate && !timer) {
fn.apply(context, args)
}
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(context, args)
}, delay)
}
}
複製代碼
指連續觸發事件可是在 n 秒中只執行一次函數。 節流會稀釋函數的執行頻率github
一個 button 按鈕,每次點擊須要提交表單。面試
<div>
<button id="button">提交</button>
</div>
<script> const button = document.getElementById('button') button.addEventListener('click', (e) => { console.log('click') }) </script>
複製代碼
上面代碼的問題是,當咱們快速點擊 button 時,每次點擊都會打印 'click',下面用節流函數優化一下。後端
const conThrottle = throttle(console.log, 2000)
const button = document.getElementById('button')
button.addEventListener('click', (e) => {
conThrottle(1)
})
function throttle(fn, time) {
let timer = null
let flag = true
return function(...args) {
let context = this
if (flag) {
fn.apply(context, args)
flag = false
timer = null
}
if (!timer) {
timer = setTimeout(() => {
flag = true
}, time)
}
}
}
複製代碼
再次測試,能夠發現無論咱們點擊的速度多麼快,在每 2 秒內,函數只會執行 1 次。app
function throttle(fn, time) {
let startTime = 0
return function(...args) {
let context = this
let endTime = Date.now()
if (endTime - startTime >= time) {
fn.apply(context, args)
startTime = endTime
}
}
}
複製代碼