1.函數(shù)防抖(debounce)
函數(shù)防抖,debounce。其概念其實是從機(jī)械開關(guān)和繼電器的“去彈跳”(debounce)衍生出來的,基本思路就是把多個信號合并為一個信號。
函數(shù)防抖就是讓某個函數(shù)在上一次執(zhí)行后, 滿足等待某個時間內(nèi)不再觸發(fā)此函數(shù)后再執(zhí)行, 而在這個等待時間內(nèi)再次觸發(fā)此函數(shù), 等待時間會重新計算。
處理諸如
resize、scroll、mousemove和keydown/keyup/keypress等DOM事件的時候,通常我們不希望這些事件太過頻繁地觸發(fā),比如input輸入框架的格式驗證,你可以隔200ms驗證一次,而不是輸入change之后立即驗證。
/**
* 函數(shù)防抖
* @param {*} fn 需要防抖的函數(shù)
* @param {*} delay 延遲執(zhí)行的時間
*/
function debounce(fn, delay) {
let timeout;
return function() {
// 保存this和參數(shù)
let context = this
let args = arguments
if(timeout) {
clearTimeout(timeout) //頻繁觸發(fā)則清除上一次,只執(zhí)行最后一次
}
timeout = setTimeout(() => {
fn.apply(context, args)
},delay)
}
}
// 測試
function fn(num){
console.log(num)
}
debounce(fn, 1000)(2) // 輸出2
2.函數(shù)節(jié)流(throttle)
函數(shù)節(jié)流有點類似函數(shù)防抖,區(qū)別就是:對于連續(xù)觸發(fā)的事件,函數(shù)防抖只執(zhí)行最后一次觸發(fā)的事件,函數(shù)節(jié)流則是降低事件發(fā)生的頻率,讓事件以較低的頻率執(zhí)行。可參考http://demo.nimius.net/debounce_throttle/
函數(shù)節(jié)流會用在比input, keyup更頻繁觸發(fā)的事件中,如resize, touchmove, mousemove, scroll。
throttle會強(qiáng)制函數(shù)以固定的速率執(zhí)行。因此這個方法比較適合應(yīng)用于動畫相關(guān)的場景。
/**
* 函數(shù)節(jié)流
* @param {*} fn 要節(jié)流的函數(shù)
* @param {*} threshhold 執(zhí)行間隔
*/
function throttle(fn, threshhold) {
let timeout = null
let start = new Date()
return function() {
// 保存this和參數(shù)
let context = this
let args = arguments
clearTimeout(timeout)
let curruent = new Date()
if(curruent - start >= threshhold) {
fn.apply(context, args)
start = curruent
} else {
timeout = setTimeout(() => {
fn.apply(context, args)
}, threshhold)
}
}
}
//測試,結(jié)果為每 5s 輸出一個3,而不是 0.5s
let test = throttle((num) => {
console.log(num)
}, 5000)
setInterval(() => {
test(3)
}, 500)