防抖节流函数
一、防抖函数
1.封装防抖函数后进行使用
mounted() {
//接收debounce返回来的函数
//this.$refs.scroll.refresh不能加(),因为要传进一个函数,加入括号变成了接收函数内部的值
const refresh = this.debounce(this.$refs.scroll.refresh, 500);
this.$bus.$on("imgLoad", () => {
refresh();//调用函数
});
},
methods: {
/**
* 构造防抖函数
*/
debounce(fun, delay) {
let timer = null;
return function(...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fun.apply(this, args);
}, delay);
};
},
}
2.使用封装的方式
//封装的debounce.js函数
//delay=50是默认值,es6语法
export function debounce(fun, delay=50) {
let timer = null;
return function(...args) {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fun.apply(this, args);
}, delay);
};
}
//增加let that=this
function debounce(fun, delay = 300) {
let timer = null
return function (...args) {
let that = this //引用this的指向
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fun.apply(that, args)
}, delay)
}
}
// 编写立即执行函数
function debounce(fn, delay, immediate = false) {
let timer = null;
let isInvoke = false;
return 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);
}
};
}
//添加了回调函数Promise和resultCallback
const input = document.querySelector('input');
const button = document.querySelector('button');
const inputFun = function () {
console.log('发送了网络请求');
return 'hello world';
};
function debounce(fn, delay, immediate = false, resultCallBack = function (res) {}) {
let timer = null;
let isInvoke = false;
const _debounce = function (...args) {
return new Promise((resolve, reject) => {
if (timer) clearTimeout(timer);
if (immediate && !isInvoke) {
try {
const result = fn.apply(this, args);
resultCallBack(result);
isInvoke = true;
resolve(result);
} catch (error) {
reject(error);
}
} else {
timer = setTimeout(() => {
try {
const result = fn.apply(this, args);
resultCallBack(result);
isInvoke = false;
timer = null;
resolve(result);
} catch (error) {
reject(error);
}
}, delay);
}
});
};
_debounce.cancel = () => {
clearTimeout(timer);
timer = null;
isInvoke = false;
};
return _debounce;
}
function foo(res) {
console.log('res :>> ', res);
}
const debounceFun = debounce(inputFun, 500, false);
const tempCallback = () => {
debounceFun().then((res) => {
console.log('我是封装的函数', res);
});
};
input.oninput = tempCallback;
//使用封装的debounce
import debounce from xxx
mounted() {
const refresh = this.debounce(this.$refs.scroll.refresh, 500);
this.$bus.$on("imgLoad", () => {
refresh();//调用函数
});
},
二、节流函数
function throttle(fun, delay = 1000) {
let pre = 0
return function (...args) {
let now = Date.now()
let that = this
if (now - pre > delay) {
fun.apply(that, args)
pre = now
}
}
}
合成版本
// 合成版
/**
* @desc 函数防抖
* @param func 目标函数
* @param wait 延迟执行毫秒数
* @param immediate true - 立即执行, false - 延迟执行
*/
function debounce(func, wait, immediate) {
let timer;
return function() {
let context = this,
args = arguments;
if (timer) clearTimeout(timer);
if (immediate) {
let callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait);
if (callNow) func.apply(context, args);
} else {
timer = setTimeout(() => {
func.apply(context, args);
}, wait)
}
}
}
/**
* @desc 函数节流
* @param func 函数
* @param wait 延迟执行毫秒数
* @param type 1 表时间戳版,2 表定时器版
*/
function throttle(func, wait, type) {
if (type === 1) {
let previous = 0;
} else if (type === 2) {
let timeout;
}
return function() {
let context = this;
let args = arguments;
if (type === 1) {
let now = Date.now();
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
} else if (type === 2) {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
}
在Vue的methods中使用
methods: {
toPay: Taro.debounce(
function() {
this.$emit("goToPay");
},
1000,
true
),
goToPay() {
console.log("123");
this.toPay();
}
}
Vue的methods中使用防抖节流:https://www.cnblogs.com/luckrain7/p/12670473.html
B站视频链接(防抖函数):https://www.bilibili.com/video/BV15741177Eh?p=175
注:以上内容仅用于日常学习