1、函数节流throttle
通俗解释:
假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯; 但是,你是个没耐心的人,你最多只会等待电梯停留一分钟; 在这一分钟内,你会开门让别人进来,但是过了一分钟之后,你就会关门,让电梯上楼。
所以throttle的作用是,预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新的时间周期。
应用:在指定时间,事件最多触发一次,如监听滚动事件。
上述例子改为 地铁 更合适。
2、函数去抖debounce
假设你正在乘电梯上楼,当电梯门关闭之前发现有人也要乘电梯,礼貌起见,你会按下开门开关,然后等他进电梯; 如果在电梯门关闭之前,又有人来了,你会继续开门; 这样一直进行下去,你可能需要等待几分钟,最终没人进电梯了,才会关闭电梯门,然后上楼。
所以debounce的作用是,当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔。
应用:百度首页的搜索按钮。
3、函数节流与函数去抖实现
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>函数节流与函数去抖</title>
</head>
<body>
<button type='button' id="btn">函数节流</button>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
const btn = document.getElementById('btn');
//函数去抖
function debounce(fn, delay) {
var timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
}
}
//函数节流
function throttle(fn, wait) {
var timer;
return function(...args) {
if(!timer) {
timer = setTimeout(() => timer = null, wait);
return fn.apply(this, args);
}
}
}
btn.onclick = debounce(function() {
console.log("clicked");
}, 300);
//按钮每500ms一次点击有效
btn.onclick = throttle(function() {
console.log("button clicked");
}, 500);
</script>
</body>
</html>
一个具体例子(lodash+vue):
<template> <div class="about"> <Button type="primary">Primary</Button> <Upload action="http://39.106.100.155:3001/file-upload/multiple-uploadll/" :data="imgData" multiple :headers="headers" > <Button icon="ios-cloud-upload-outline">Upload files</Button> </Upload> </div> </template> <script> import _ from "lodash"; export default { data() { return { imgData: { userName: "test" }, headers: { token: "123" } }; }, methods: { test() { console.log("click"); this.debounce(); this.throttle(); } }, created() { let i = 0; // 在 0.5s 秒内最多执行 func 一次的函数。 this.debounce = _.debounce(() => { console.log("debounce"); }, 500); // 在 0.5s 秒内最多执行 func 一次的函数。 this.throttle = _.throttle(() => { console.log("throttle"); }, 500); let time = setInterval(() => { // this.test(); if (i > 9) { clearInterval(time); } this.test(); i++; }, 100); } }; </script>
控制台输出:
throttle 每0.5s就执行一次了。
而debounce 只执行了一次。