基础实现
function debounce(fn, delay) {
// 1.定义一个定时器, 保存上一次的定时器
let timer = null
// 2.真正执行的函数
const _debounce = function() {
// 取消上一次的定时器
if (timer) clearTimeout(timer)
// 延迟执行
timer = setTimeout(() => {
// 外部传入的真正要执行的函数
fn()
}, delay)
}
return _debounce
}
this参数
function debounce(fn, delay) {
// 1.定义一个定时器, 保存上一次的定时器
let timer = null
// 2.真正执行的函数
const _debounce = function(...args) {
// 取消上一次的定时器
if (timer) clearTimeout(timer)
// 延迟执行
timer = setTimeout(() => {
// 外部传入的真正要执行的函数
fn.apply(this, args)
}, delay)
}
return _debounce
}
立即执行(输入第一次先立即执行,之后在防抖)
function debounce(fn, delay, immediate = false) {
// 1.定义一个定时器, 保存上一次的定时器
let timer = null
// 判断是否立即执行
let isInvoke = false
// 2.真正执行的函数
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
}
取消功能(防抖未执行请求前,取消本地请求)
function debounce(fn, delay, immediate = false) {
// 1.定义一个定时器, 保存上一次的定时器
let timer = null
let isInvoke = false
// 2.真正执行的函数
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
timer = null
}, delay)
}
}
// 封装取消功能
_debounce.cancel = function() {
if (timer) clearTimeout(timer)
timer = null
isInvoke = false
}
return _debounce
}
返回值
function debounce(fn, delay, immediate = false, resultCallback) {
// 1.定义一个定时器, 保存上一次的定时器
let timer = null
let isInvoke = false
// 2.真正执行的函数
// 2种方式
// 1resultCallback回调函数
// 2Promise
const _debounce = function(...args) {
return new Promise((resolve, reject) => {
// 取消上一次的定时器
if (timer) clearTimeout(timer)
// 判断是否需要立即执行
if (immediate && !isInvoke) {
const result = fn.apply(this, args)
if (resultCallback) resultCallback(result)
resolve(result)
isInvoke = true
} else {
// 延迟执行
timer = setTimeout(() => {
// 外部传入的真正要执行的函数
const result = fn.apply(this, args)
if (resultCallback) resultCallback(result)
resolve(result)
isInvoke = false
timer = null
}, delay)
}
})
}
// 封装取消功能
_debounce.cancel = function() {
if (timer) clearTimeout(timer)
timer = null
isInvoke = false
}
return _debounce
}
使用
<!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>
//引入封装的防抖函数
<script src="./05_debounce-v5-函数返回值.js"></script>
<script>
const inputEl = document.querySelector("input")
let counter = 0
const inputChange = function(event) {
console.log(`发送了第${++counter}次网络请求`, this, event)
// 返回值
return "返回值"
}
// 防抖处理
const debounceChange = debounce(inputChange, 3000, false, (res) => {
// 获取回到函数返回值
console.log("拿到真正执行函数的返回值:", res)
})
// 获取Promise返回值
const tempCallback = () => {
debounceChange().then(res => {
console.log("Promise的返回值结果:", res)
})
}
inputEl.oninput = tempCallback
// 取消功能
const cancelBtn = document.querySelector("#cancel")
cancelBtn.onclick = function() {
debounceChange.cancel()
}
</script>
</body>
</html>