节流与防抖(简单粗暴,拿来即用)
防抖和节流严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。所以还是很有必要早点掌握的。
防抖和节流的区别:
节流是将多次执行变为每隔一段时间执行(多次点击,在时间内,只执行第一次)
防抖是将多次执行变为最后一次执行(多次点击,只执行最后一次)
(一)、函数的节流与防抖的封装使用
(1)创建一个public.js文件 存放节流方法
/**
1. 函数节流(分页加载点击事件使用)
2. @param fn
3. @param interval
4. @returns {Function}
5. @constructor
*/
export const Throttle = (fn, t) => {
let last;
let timer;
let interval = t || 500;
return function() {
let args = arguments;
let now = +new Date();
//等待执行
if (last && now - last < interval) {
clearTimeout(timer);
timer = setTimeout(() => {
// fn.apply(this, args); //非立即执行,则在wait毫秒内的结束处执行,快速点击N下的时候不需要触发函数
last = now;
}, interval);
} else {
fn.apply(this, args);//立即执行,则在wait毫秒内开始时执行
last = now;
}
}
}
/**
* 函数防抖 (搜索框搜索使用)
* @param fn
* @param delay
* @returns {Function}
* @constructor
*/
export const Debounce = (fn, t) => {
let delay = t || 500;
let timer;
return function() {
let args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
timer = null;
fn.apply(this, args);
}, delay);
}
};
export const Debounce2 = (fn, t) => {
let time = t || 500;
let timeout = null;
return function() {
clearTimeout(timeout)
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, time);
}
};
(2)页面中引入public.js文件
import { Throttle,Debounce,Debounce2 } from "@/utils/public.js";
(3)节流事件的使用
/**搜索 Throttle(function( 参数 ) */
handleSearchList:Throttle(function(){
this.listQuery.pageNum = 1;
this.getList();
console.log("搜索请求信息~ ",this.listQuery);
},3000),
(二)、函数的节流与防抖的快捷使用法
(1)函数节流
函数节流(throttle):当持续触发事件时,保证在一定时间内只调用一次事件处理函数
实现函数节流我们主要有两种方法:时间戳和定时器
时间戳方法: 利用时间戳让第一次执行事件,此后每隔3000ms 执行,小于这段时间不会执行
定时器方法:先将设置的定时器设置为null,第一次触发事件,达到时间后再执行这个函数,并初始化定时器
- 使用方法:先在data中定义字段,在methods中定义节流方法及使用
//定义节流时间(data中定义字段)
preTime:0,
/*节流方法(时间戳精简版)
//1.先定义一个 preTime = 0 赋予初始值 ,为第一次点击
//2.获取当前时间戳 - preTime 判断是否大于延迟时间
//3.执行之后 将now 当前时间的时间戳进行赋值 preTime
*/
throttle(fn, delay = 3000) {
let pre = this.preTime // 初始值是 0
let that = this
return function() {
let now = +new Date();
if (now - pre >= delay) {
fn.apply(this, arguments)
that.preTime = now;
}
}
},
//使用方法
toSaveGoods(){
let that = this ;
//节流方法
this.throttle(function(){
that.saveGoods();//执行的方法
},3000)()
},
/**
节流方法集成版
* @param { function } func 函数
* @param { number } wait 延迟执行毫秒数
* @param { number } type 1 表时间戳版,2 表定时器版
*/
先定义要使用的属性(data中定义字段)
previous:0,
timeout:null,
throttle_pro(func, wait ,type) {
let that = this;
console.log(' throttle_pro -->',type)
let previous, timeout;
if(type===1){
previous = this.previous;
}else if(type===2){
timeout = this.timeout;
}
return function() {
let context = this;
// arguments 是一个对应于传递给函数的参数的类数组对象
let args = arguments;
if(type===1){
let now = Date.now();
if (now - previous >= wait) {
func.apply(context, args);
that.previous = now;
}
}else if(type===2){
if (!timeout) {
that.timeout = setTimeout(() => {
that.timeout = null;
func.apply(context, args)
}, wait)
}
}
}
},
toPerformThrottle_pro(type){
let that = this;
//节流方法
this.throttle_pro(function() {
//that.saveGoods();//执行的方法
that.toPerform_pro();
}, 3000,type)()
},
toPerform_pro(){
console.log(' 集成版的节流 ');
}
效果展示:
(2)函数防抖
防抖(debounce):所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
防抖函数分为:非立即执行版和立即执行版。
//防抖,定义一个定时器 (data中定义字段)
debounce_timeout:null,
//防抖优化版
d_timeout:null
/* 函数的防抖
//( 滚动加载时使用较好,当持续触发事件时,一定时间段内没有再触发事件,
//事件处理函数才会执行一次 )
*/
debounce(fn, wait) {
let that = this
let timeout = this.debounce_timeout; //定义一个定时器
return function() {
if(timeout !== null)
clearTimeout(that.debounce_timeout); //清除这个定时器
that.debounce_timeout = setTimeout(fn, wait);
}
},
debouncePerform(){
let that = this;
this.debounce(function() {
that.debounceConsole();
}, 3000)()
},
debounceConsole(){
console.log(' 执行防抖函数 ');
},
/**
* 函数防抖优化版
* @param { function } func
* @param { number } wait 延迟执行毫秒数
* @param { boolean } immediate true 表立即执行,false 表非立即执行
*/
debounce_pro(func,wait,immediate) {
let that = this;
let timeout = this.d_timeout; // 获取定义的定时器
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout); //有值,清除定时器任务
if (immediate) {
let callNow = !timeout;
that.d_timeout = setTimeout(() => {
that.d_timeout = null;
}, wait);
if (callNow) func.apply(context, args)
}else {
that.d_timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
},
debouncePerformPro(immediate){
let that = this;
this.debounce_pro(function() {
that.debounceConsole();
}, 3000,immediate)()
}
效果展示: