简介
节流和防抖是前端面试中老生常谈的话题,能大大提升程序的性能。但是节流防抖具体是什么?什么情况下使用呢?以及在Vue中应该怎么使用呢?下面请跟随笔者的脚步给大家逐步介绍。
防抖(debounce)
所谓防抖,就是指单位时间内函数只执行一次,如果在单位时间内重复触发该事件,则会重新计算函数执行时间。
防抖又分为两种,分为立即执行版本和非立即执行版本。
立即执行版本
立即执行版本我们一般可以用在按钮点击上(比如提交表单),点击立即触发,单位时间内一直点击不会触发。当超过单位时间再次点击会再次触发。
function debounce1(func, delay) {
let timer = null
return function() {
const context = this
const args = arguments
if(timer) clearTimeout(timer)
const canCall = !timer
timer = setTimeout(() => {
timer = null
}, delay)
// if(canCall) func.apply(context, args)
if(canCall) func.call(context, ...args)
}
}
复制代码
非立即执行版本
非立即执行版本我们可以应用在搜索联想功能中,输入内容的时候不触发,输入完后再请求后端获取数据。
function debounce2(func, delay) {
let timer = null
return function() {
const context = this
const args = arguments
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
//func.apply(context, args)
func.call(context, ...args)
},delay)
}
}
复制代码
组合版本
function debounce3(func, delay, immediate=true) {
let timer = null
return function() {
const context = this
const args = arguments
if(timer) clearTimeout(timer)
if(immediate) {
const canCall = !timer
timer = setTimeout(() => {
timer = null
},delay)
// if(canCall) func.apply(context, args)
if(canCall) func.call(context, ...args)
} else {
timer = setTimeout(() => {
//func.apply(context, args)
func.call(context, ...args)
},delay)
}
}
}
复制代码
节流(throttle)
所谓节流,就是单位时间内不管触发多少次函数,只固定执行一次函数。 节流会降低函数的执行频率。
节流我们一般用在单位时间内只需执行一次的场景,比如视频播放进度的保存、游戏里面的子弹射击、鼠标移动事件、窗口大小缩放事件、滚动条滚动事件等等,如果还有更好的场景欢迎评论区补充。
节流有定时器版本和时间戳版本。
定时器版本
function throttle1(func, delay) {
let timer = null;
return function () {
const context = this;
const args = arguments;
if (!timer) {
timer = setTimeout(() => {
timer = null;
// func.apply(context, args);
func.call(context, ...args);
}, delay);
}
};
}
复制代码
时间戳版本
function throttle2(func, delay) {
let pre = 0;
return function () {
const context = this;
const args = arguments;
let now = Date.now();
if (now - pre > delay) {
pre = now;
// func.apply(context, args);
func.call(context, ...args);
}
};
}
复制代码
组合版本
function throttle3(func, delay, timestamp=true) {
let timer = null
let pre = 0
return function() {
const context = this
const args = arguments
if(timestamp) {
let now = Date.now()
if(now - pre > delay) {
pre = now
//func.apply(context, args)
func.call(context, ...args)
}
} else {
if(!timer) {
timer = setTimeout(() => {
timer = null;
// func.apply(context, args);
func.call(context, ...args);
}, delay)
}
}
}
}
复制代码
Vue中使用
很多小伙伴虽然知道防抖和节流,但是却不知道在Vue中如何使用节流和防抖,下面笔者介绍两种在Vue中使用防抖和节流的方法。
方法1
通过外部引入的方式。
防抖
import { debounce } from "@/utils/index";
export default {
mounted() {
window.addEventListener("scroll", this.handleScroll);
},
methods: {
handleScroll: debounce(function (e) {
console.log(e);
}, 1000),
},
};
复制代码
节流
import { throttle } from "@/utils/index";
export default {
mounted() {
window.addEventListener("scroll", this.handleScroll);
},
methods: {
handleScroll: throttle(function (e) {
console.log(e);
}, 1000),
},
};
复制代码
方法2
写在本文件里面。
防抖
mounted() {
window.addEventListener("scroll", this.debounce(this.handleScroll, 1000));
},
methods: {
debounce(func, delay) {
let timer = null;
return function () {
const context = this;
const args = arguments;
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args);
}, delay);
};
},
handleScroll(e) {
console.log(e);
},
},
复制代码
节流
mounted() {
window.addEventListener("scroll", this.throttle(this.handleScroll, 1000));
},
methods: {
throttle(func, delay) {
let timer = null;
return function () {
const context = this;
const args = arguments;
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args);
}, delay);
};
},
handleScroll(e) {
console.log(e);
},
},
复制代码
后记
本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!
作者:苏苏同学
链接:https://juejin.cn/post/7044818549751152647
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。