什么是防抖函数
防抖函数用于限制触发函数或网络请求的次数,例如百度搜索中,当按下键盘之后会在一定时间内确认不在输入时再发送网络请求。
防抖函数的实现(1),思路是通过定时器来执行函数
function debounce(fn, delay) {
let timer = null
const _debounce = function(...args) {
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
return _debounce
}
防抖函数的实现(2) 增加一个参数是否可以立即执行一次
function debounce(fn, delay, immediate = false) {
let timer = null
let isInvoke = false
const _debounce = function (...args) {
if (timer) clearTimeout(timer)
if (immediate && !isInvoke) {
fn.apply(this, args)
isInvoke = true
} else {
timer = setTimeout(() => {
fn.apply(this, args)
isInvoke = false
}, delay)
}
}
return _debounce
}
防抖函数的实现(3) 增加一个取消执行的功能
function debounce(fn, delay, immediate = false) {
let timer = null
let isInvoke = false
const _debounce = function (...args) {
if (timer) clearTimeout(timer)
if (immediate && !isInvoke) {
fn.apply(this, args)
isInvoke = true
} else {
timer = setTimeout(() => {
fn.apply(this, args)
isInvoke = false
}, delay)
}
}
_debounce.cancel = function() {
if(timer) clearTimeout(timer)
timer = null
}
return _debounce
}
防抖函数的实现(4) 拿到函数的返回值
function debounce(fn, delay, immediate = false, resultCallback) {
let timer = null
let isInvoke = false
const _debounce = function (...args) {
if (timer) clearTimeout(timer)
if (immediate && !isInvoke) {
const result = fn.apply(this, args)
if(resultCallback) resultCallback(result)
isInvoke = true
} else {
timer = setTimeout(() => {
const result = fn.apply(this, args)
if(resultCallback) resultCallback(result)
isInvoke = false
}, delay)
}
}
_debounce.cancel = function() {
if(timer) clearTimeout(timer)
timer = null
}
return _debounce
}
HTML部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text">
<button id="cancel">取消</button>
<script src="./01_防抖函数的基本实现.js"></script>
<script>
const inputEl = document.querySelector("input")
const btn = document.querySelector("#cancel")
let counter = 0
const inputChange = function () {
console.log(`发送了第${++counter}次网络请求`);
return 'aaa'
}
const debounceChange = debounce(inputChange, 2000, true, (res) => {
console.log(res);
})
inputEl.oninput = debounceChange
btn.onclick = debounceChange.cancel
</script>
</body>
</html>