拋開lodash,手寫節流和防抖函式
阿新 • • 發佈:2020-10-20
面試的時候我們經常會問別人是理解什麼是節流和防抖,嚴格的可能要求你寫出節流和防抖函式,這裡我們拋開loadsh工具庫手寫節流和防抖
節流函式throttle
// 節流方案1,每delay的時間執行一次,通過開關控制
function throttle(fn, delay, ctx) {
let isAvail = true
return function () {
let args = arguments // 開關開啟時,執行任務
if (isAvail) {
fn.apply(ctx, args)
isAvail = false // delay時間之後,任務開關開啟
setTimeout(function () { isAvail = true }, delay)
}
}
}
// 節流方案2,通過計算開始和結束時間
function throttle(fn,delay){
// 記錄上一次函數出發的時間
var lastTime = 0
return function(){
// 記錄當前函式觸發的時間
var nowTime = new Date().getTime()
// 噹噹前時間減去上一次執行時間大於這個指定間隔時間才讓他觸發這個函式
if(nowTime - lastTime > delay){
// 繫結this指向
fn.call(this)
//同步時間
lastTime = nowTime
}
}
}
東莞vi設計https://www.houdianzi.com/dgvi/ 豌豆資源網站大全https://55wd.com
2.防抖debounceTail
2.1)只執行首次
// 防抖 且首次執行
// 採用原理:第一操作觸發,連續操作時,最後一次操作開啟任務開關(並非執行任務),任務將在下一次操作時觸發)
function debounceStart(fn, delay, ctx) {
let immediate = true
let movement = null
return function() {
let args = arguments
// 開關開啟時,執行任務
if (immediate) {
fn.apply(ctx, args)
immediate = false
}
// 清空上一次操作
clearTimeout(movement)
// 任務開關開啟
movement = setTimeout(function() {
immediate = true
}, delay)
}
}
2.2)只執行最後一次
// 防抖 尾部執行
// 採用原理:連續操作時,上次設定的setTimeout被clear掉
function debounceTail(fn, delay, ctx) {
let movement = null
return function() {
let args = arguments
// 清空上一次操作
clearTimeout(movement)
// delay時間之後,任務執行
movement = setTimeout(function() {
fn.apply(ctx, args)
}, delay)
}
}