函数防抖(debounce)的应用场景
连续的事件,只需触发一次的回调场景有:
搜索框搜索输入。
只需要用户最后一次输入完再发送请求 手机号、邮箱格式的输入验证检测
窗口大小的resize 。只需窗口调整完成后,计算窗口的大小,防止重复渲染
函数节流(throttle)的应用场景
间隔一段时间执行一次回调的场景有:
滚动加载,加载更多或滚动到底部监听
谷歌搜索框,搜索联想功能
高频点击提交,表单重复提交
省市信息对应字母快速选择
1.防抖
export const boDebounce = (func, wait, immediate) => {
console.log("进入防抖");
let timeout;
return function () {
const context = this;
const args = [...arguments];
if (timeout) clearTimeout(timeout);
if (immediate) {
const callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
}
使用:
<template>
<div>
<el-input v-model="input" @input="getSearch"> </el-input>
<el-input v-model="nowInput" @input="getNowSearch"> </el-input>
</div>
</template>
<script>
import { debounce, nowDebounce } from "@/store/debounce.js";
export default {
data() {
return {
input: "",
nowInput: "",
};
},
methods: {
getSearch: boDebounce(
function () {
console.log("拿到数据");
},
1000,
false
),
getSearch: debounce(function () {
console.log("拿到数据");
}, 1000),
getNowSearch: nowDebounce(function () {
console.log("立即拿到数据");
}, 1000),
},
};
</script>
2.节流
export const boThrottle = (func, wait, type) => {
console.log("进入节流")
let previous;
let timeout
if (type === "now") {
previous = 0;
} else if (type === "late") {
timeout;
}
return function () {
let context = this;
let args = arguments;
if (type === "now") {
let now = Date.now();
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
} else if (type === "late") {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
}
使用:
<template>
<div>
<div class="mouseDiv" @mousemove="mouseNoMoveEvent">{{ mouseNowNum }}</div>
<div class="mouseDiv" @mousemove="mouseMoveEvent">{{ mouseNum }}</div>
</div>
</template>
<script>
import {
throttle,
nowThrottle,
boThrottle
} from "@/store/debounce.js";
export default {
data() {
return {
mouseNowNum: 0,
mouseNum: 0,
};
},
methods: {
mouseNoMoveEvent: nowThrottle(function () {
this.mouseNowNum++;
console.log("立即执行");
}, 1000),
mouseMoveEvent: throttle(function () {
this.mouseNum++;
console.log("延迟执行");
}, 1000),
mouseNoMoveEvent: boThrottle(
function () {
this.mouseNowNum++;
console.log("立即执行");
},
1000,
"now"
),
mouseMoveEvent: boThrottle(
function () {
this.mouseNum++;
console.log("延迟执行");
},
1000,
"late"
),
},
};
</script>
<style>
.mouseDiv {
margin: 20px auto;
width: 1000px;
height: 400px;
line-height: 400px;
text-align: center;
font-size: 30px;
background-color: lightblue;
}
</style>
3.节流 时间戳版,立即执行版
export const nowThrottle = (func, wait) => {
console.log("进入节流")
var previous = 0;
return function () {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
4.节流 计时器版,延迟执行版
export const throttle = (func, wait) => {
console.log("进入节流")
let timeout;
return function () {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}