节流和防抖的理解

节流


什么是节流? 节流的目的?

节流指尽可能减少不必要的开支 ,消耗更少的资源办更多的事

节流的理解

原理是通过判断是否到达一定时间来触发函数

为什么要节流?

在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。

简陋的实现

<script>
let body = document.body;
let start = 0;
let key = false;
body.onmousemove = function () {
throttle1(300, function () {
console.log(1);
})
};
// 方法1 通过触发事件的时间间隔,判断节流处理
function throttle1(delay, fn) {
if (!start) start = Date.now();
let currentTime = Date.now();
if (currentTime - start > delay) {
fn(); start = 0;
}
}
// 方法2 通过上锁的方式做节流处理(如果代码执行中,则终止操作)
function throttle2(delay, fn) {
if (key) return false;
key = true; setTimeout(function () {
fn();
key = false;
}, delay)
}
</script>

防抖


什么是防抖?

所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

防抖的目的

在一定时间内的几次操作合并为一次操作进行。

防抖的理解

原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

简陋的实现

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>防抖 - debounce</title>
</head>
<body>
<input type="text" id="ipt">
</body>
</html>
<script>
let ipt = document.querySelector('#ipt');
let timer;

ipt.onkeyup = function () {
debounce(2000, function () {
console.log(1);
})
};

/**
* 防抖封装函数 - 应用场景(联想查询)
*/
function debounce(delay, fn) {
if (timer) clearTimeout(timer);
timer = setTimeout(fn, delay)
}
</script>

代码封装

/**
* 防抖函数
* @param method 事件触发的操作
* @param delay 多少毫秒内连续触发事件,不会执行
* @returns {Function}
*/
export const debounce = (method, delay) => {
let timer = null;
return function () {
let self = this,
args = arguments;
timer && clearTimeout(timer);
timer = setTimeout(function () {
method.apply(self, args);
}, delay);
}
}


/**
* 节流函数
* @param method 事件触发的操作
* @param mustRunDelay 间隔多少毫秒需要触发一次事件
*/
export const throttle = (method, mustRunDelay) => {
let timer,
args = arguments,
start;
return function loop() {
let self = this;
let now = Date.now();
if (!start) {
start = now;
}
if (timer) {
clearTimeout(timer);
}
if (now - start >= mustRunDelay) {
method.apply(self, args);
start = now;
} else {
timer = setTimeout(function () {
loop.apply(self, args);
}, 100);
}
}
}