前言
现在发现面试时候考察的防抖截流这个问题考察的东西不只这么简单了 面试官会结合各种应用案例去考察,比如模糊搜索能想到的优化有哪些等等,因此防抖截流函数应该深刻的研究一下并且扩展应用,自己之前一直忙加懒🤪。。。为了心仪的offer 现在要挤时间学习了💪
一、防抖
特征:举个🌰,电梯来了之后,每一个进电梯的人都是一个个事件,电梯会等待全部人员进入之后再运行。前端再发起多次ajax请求的时候,就会以最后一次请求为准
<input id="debounce" />
<input id="throttle" />
<script>
window.onload = function() {
function ajax(content) {
console.log('ajax request ' + content)
}
function debounce(fun, delay) { //利用闭包将timer存在自己得作用域(简单的讲闭包就是在函数里面定义的函数)
let timer = null;
return function (args) {
let that = this
let _args = args
clearTimeout(timer)
timer = setTimeout(function () {
fun.call(that, _args)
}, delay)
}
}
let input2 = document.getElementById('debounce')
let debounceAjax = debounce(ajax, 3000) //此处很重要!需要引用才会生成闭包,不然timer就会被垃圾回收掉导致之前的请求依然会发送不会被清除
input2.addEventListener('keyup', function (e) {
debounceAjax(e.target.value) //如果写成debounce()(ajax, 3000)这样,就不会产生引用 不会生成闭包
})
}
</script>
注意上面的注释,需要引用一下才可以生成闭包,不然timer会被垃圾回收掉,之前的请求依然会执行
应用场景
- 模糊搜索请求后端返回数据的时候加上防抖 另外面试的时候 还问了如何防止之前请求返回延迟影响显示的结果,要么在服务端存token,要么取最后一次结果
- 购物网站web页面的左边一般有一个分类栏 鼠标移上去的时候会出现三级分类,这个分类出现控制也是利用了防抖函数
二、节流
特征:节流函数举个🌰,比如高铁在中途的一站固定停车三分钟发车
function throttle(fn,delay) {
let can = false;
return function () {
let args = arguments[0];
let that = this;
if(can) return;
can = true;
setTimeout(function() {
fn.call(that, args);
can = false;
}, delay)
}
}
let input3 = document.getElementById('throttle');
let throttleAjax = throttle(ajax, 2000)
input3.addEventListener('keyup', function (e) {
throttleAjax(e.target.value)
})
应用场景:
- 监听滚动事件,滚动时候请求后端的时候。或者滑到底部自动加载更多,用throttle来判断
- 另外还有做商品预览图的放大镜效果时,不必每次鼠标移动都计算位置
再来简单提一下闭包的概念
其实上述的防抖截流都是利用了闭包的特性 闭包一定不能是自身的引用 得是对象和对象之间引用才行
function a() {
var i = 0;
return function () {
i++;
console.log(i);
}
}
a()();
a()(); // 没有引用所以导致i被垃圾回收
function a() {
var i = 0;
return function () {
i++;
console.log(i);
}
}
var b = a(); // 引用才不会导致i被垃圾回收
b(); // 1
b(); // 2