![4f3d890c7763ec1a28f19c8defd87e58.png](https://i-blog.csdnimg.cn/blog_migrate/5ce521831e844d2805a8bc146c419d98.jpeg)
Q:函数为什么会抖呢? A:可能是年级大了吧。
![720a7a401ca8491501d7e45a4782c6ea.gif](https://i-blog.csdnimg.cn/blog_migrate/aa87c93fd07d5622a1c0da26293ee158.gif)
来列举一个实际的应用场景,例如百度的搜索提示
![778271955e45b97faa9e20409db48b57.gif](https://i-blog.csdnimg.cn/blog_migrate/423638f9897bff6f2fffe9be1b67ca94.gif)
你可以看到, 当你在输入框每输入一个字符的时候
百度都会不断的根据当下的输入给予新的提示
那么,如果有一个人打字速度非常快
他以迅雷不及掩耳盗铃儿响叮当之势,输入了helloworld这个单词
仅用了200毫秒
这时键盘事件函数被连续触发了10次
我们把这称之为函数抖动。
抖动并不是问题,问题是
他每按下一次键盘,浏览器都会向服务器做一次查询
浏览器一共会向服务器发出10次请求!
显然,对于这个手速极快的男人来说
这并不是 他想要的
那我们至少浪费了9次查询,无端的增加了服务器的压力。
所以,接下来怎么办呢?
解决思路是这样的:
当用户按下键盘后,我们不要立刻向服务器发起请求
而是等待300ms
如果接下来300ms内,用户不再输入内容。
则表示他已经把想要查询的单词写完了
这个时候我们再发起请求查询搜索提示
就大大的避免了浪费
怎么样? 这个想法是不是特别棒?!
说做就做,我们来动手实现以下代码:
- 这是未做防抖处理的代码
inputEle.addEventListener("keyup", function(e){
//ajax(...); 发送请求到服务器
})
- 这是做了防抖处理的代码(未优化版本)
var t = null;
inputEle.addEventListener("keyup", function(e){
clearTimeout(t);
t = setTimeout(function(){
//ajax(...); 发送请求到服务器
}, 300);
})
如果你仔细的阅读了上面的代码,依然不能理解防抖原理
我还有张原理图给你看
![68997b1a64dbf073f44419794f95a6bf.png](https://i-blog.csdnimg.cn/blog_migrate/3a617e386167b25f0a89db2abddb1c8b.png)
接下来,由于该男人手速过快
![d16fa71a9305038eee13263d338749bf.png](https://i-blog.csdnimg.cn/blog_migrate/4e74b0b93ce45088595fe6911bd03d5c.jpeg)
总结
只要在300ms连续触发键盘事件,新的定时器总是会替代旧的定时器
那么,连续过快的键盘输入,将不会触发多次请求
而是在键盘输入结束后(300ms内不再输入)发出一次请求
回过头来,我们再看代码
var t = null;
inputEle.addEventListener("keyup", function(e){
clearTimeout(t); //每次触发,都把前面的定时器关闭,尽管第一次定时器并不存在
t = setTimeout(function(){ //开启新的定时器
//ajax(...); 发送请求到服务器
}, 300);
})
是不是好理解一些了呢
不过这段代码,我们显然写的不够完美
为了解决防抖问题,我们引入了全局变量t,造成了全局变量污染。
于是,我们接下来再对代码做一次优化:
inputEle.addEventListener("keyup", (function(e){ //这是一个自运行函数
var t = null;
return function(){ //真正的事件函数在这里
clearTimeout(t); //每次触发,都把前面的定时器关闭,尽管第一次定时器并不存在
t = setTimeout(function(){ //开启新的定时器
//ajax(...); 发送请求到服务器
}, 300);
}
})())
为什么要用自运行函数?
当然是为了解决全局变量的问题啊
inputEle.addEventListener("keyup", (function(e){ //自运行函数会立刻执行并返回
var t = null; //变成了局部变量,不会造成全局污染
return 真正的函数;
})())
此文转载自:千锋HTML5学院
原文链接:如何讲清楚函数防抖?
相关知识:
Eric:如何讲清楚函数节流?zhuanlan.zhihu.com![58b361a26e3fb10c655ce0a91fd91960.png](https://i-blog.csdnimg.cn/blog_migrate/02c74f465b4dafcd431fac24f801e493.jpeg)