手写防抖函数
将自己的理解和知识点写在代码注释中.(习惯了)
debounce-v1-基本实现
function debounce(fn, delay = 1000) {
// 定义定时器,保存上一次的定时器
let timer = null
function _debounce(){
// 取消上一次的定时器
if(timer) clearTimeout(timer)
// 延迟执行
timer = setTimeout(() => {
// 真正要执行的函数
fn()
}, delay);
}
return _debounce
}
debounce-v2-this-参数
function debounce(fn, delay = 1000) {
// 定义定时器,保存上一次的定时器
let timer = null
function _debounce(...args){
// 取消上一次的定时器
if(timer) clearTimeout(timer)
// 延迟执行
timer = setTimeout(() => {
// 真正要执行的函数
fn.apply(this, args)
}, delay);
}
return _debounce
}
debounce-v3-立即执行
function debounce(fn, delay = 1000, immediate = false) {
// 定义定时器,保存上一次的定时器
let timer = null
// 判断是否需要执行
let isInvoke = false
function _debounce(...args){
// 取消上一次的定时器
if(timer) clearTimeout(timer)
// 判断是否需要立即执行
if(immediate && !isInvoke){
fn.apply(this, args)
isInvoke = true
timer = null
}
// 延迟执行
timer = setTimeout(() => {
// 真正要执行的函数
fn.apply(this, args)
isInvoke = false
}, delay);
}
return _debounce
}
debounce-v4-取消功能
function debounce(fn, delay = 1000, immediate = false) {
// 定义定时器,保存上一次的定时器
let timer = null
// 判断是否需要执行
let isInvoke = false
function _debounce(...args){
// 取消上一次的定时器
if(timer) clearTimeout(timer)
// 判断是否需要立即执行
if(immediate && !isInvoke){
fn.apply(this, args)
isInvoke = true
timer = null
}
// 延迟执行
timer = setTimeout(() => {
// 真正要执行的函数
fn.apply(this, args)
isInvoke = false
}, delay);
}
// 封装取消功能
_debounce.cancel = () => {
if(timer){
clearTimeout(timer)
timer = null
isInvoke = false
}
}
return _debounce
}
debounce-v5-函数返回值
function debounce(fn, delay = 1000, immediate = false, resultCallback) {
// 定义定时器,保存上一次的定时器
let timer = null
// 判断是否需要执行
let isInvoke = false
function _debounce(...args){
// 取消上一次的定时器
if(timer) clearTimeout(timer)
// 判断是否需要立即执行
if(immediate && !isInvoke){
const result = fn.apply(this, args)
if(resultCallback && result && typeof resultCallback === 'function') {
resultCallback(result)
}
isInvoke = true
timer = null
}
// 延迟执行
timer = setTimeout(() => {
// 真正要执行的函数
const result = fn.apply(this, args)
if(resultCallback && result && typeof resultCallback === 'function') {
resultCallback(result)
}
isInvoke = false
}, delay);
}
// 封装取消功能
_debounce.cancel = () => {
if(timer){
clearTimeout(timer)
timer = null
isInvoke = false
}
}
return _debounce
}
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" placeholder="请输入商品名~" />
<button id="btn">取消</button>
<!-- <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.2/underscore-umd-min.js"></script> -->
<!-- <script src="./01_debounce-v1-基本实现.js"></script> -->
<!-- <script src="./02_debounce-v2-this-参数.js"></script> -->
<!-- <script src="./03_debounce-v3-立即执行.js"></script> -->
<!-- <script src="./04_debounce-v4-取消功能.js"></script> -->
<script src="./05_debounce-v5-函数返回值.js"></script>
<script>
const inputEl = document.querySelector("input");
let index = 0;
const inputFn = function (event) {
console.log(`执行第${++index}次`, this, event);
return "aaaaa";
};
/// 1.深刻理解: 回城防抖 平A节流
// 2.underscore库的使用
// 防抖处理
// const newInputFn = _.debounce(inputFn, 1000);
// 节流处理
// const newInputFn = _.throttle(inputFn, 1000);
// 3.自己手写防抖
const newInputFn = debounce(inputFn, 2000, true, (res) => {
console.log("拿到函数的返回值:", res);
});
inputEl.addEventListener("input", newInputFn);
// 取消功能
const btnEl = document.querySelector("#btn");
btnEl.addEventListener("click", () => {
newInputFn.cancel();
});
</script>
</body>
</html>