?今日头条出的题目是写一个防抖函数,,根据用户输入的词语,提交后端进行模糊查询,按输入次序显示服务器返回结果。
?
?原题目,面试官写的是注意防抖和次序。
他的要求是:?比如输入非常快的提交了三次 a, b,c 三个字母。由于服务器响应慢,客户端已经提交c查询,但是服务器才返回的b的查询结果(这个用闭包,其实来闭包也有问题,典型如何处理异常)。
? 面试官出的这道题的确很有代表性,前端开发中经常会遇到的问题,重复执行,表单重复提交,不管前后端开发都应该了解。这个题跟我大约2012年6月,腾讯网www.qq.com 首页改版上线,做的一个搜索模块很相似, 那时候在腾讯是我职业生涯中第一个前端开发工作。
? 当时这个项目,填了几个坑:
1.必须用原生javascript代码,腾讯网首页那时候可不让你引入jquery,引入一个大js这么大的访问量得浪费多少钱?:)
2.就是层遮盖的问题,输入关键字 关键字弹层是摊在输入框下方,那时候搜索框下面有flash,一不小心就被flash盖住
最坑的是还有飞来飞去的广告
3.其次就是后端返回的智能提示元素个数不相同,还有可能不返回,元素个数不同,就需要代理机制,冒泡到上层处理
4.另外就是css的问题,网页/图片/视频等栏目蓝色框是要覆盖的,各位看官仔细看,鼠标移动到“网页”下拉前下面是蓝色边框,移动过去后变没了。最先版本还记录用户鼠标从哪移的,点击了那个栏目,再跟关键词点击关联就跟复杂了。
5. 因为这个作为一个模块,就是css动态加载,动态加载简单,加载进来能用,不跟其他人冲突,处理起来也琐碎。
6.与分类栏目相关的关键词搜索,以及日志记录
7.异常处理
另外就是面试官说的那两个问题。我觉得最经典的就是防抖。虽然简单,但却经典,稍后介绍。
?
我做项目的那会儿,不知道是否是学艺不精,不知道有防抖的概念,那?下面就来介绍一下防抖。下面的代码测试一下,就会浪费很多资源执行程序,这里仅是输出了console.log(),对资源消耗不大,如果数据库批量查询影响就很大了。运行下面的程序,打开浏览器,滚动滚动条或者放大缩小窗口,浏览器控制台就会输出一堆log。
防抖函数:一个频繁触发的操作,在规定时间内,只让最后一次生效,前面的不生效。
? 看防抖函数debounce(fn,delay),delay参数是1秒,1秒调用防抖函数不管多少次,只执行一次。
防抖从字面的意思很好理解。典型的应用就是拍照,估计大家都有印象,不防抖的相机拍出来的照片有一堆重影。防抖就是让相机只拍一次。
上面项目需要防抖就是鼠标在 分类区域 移动的时候,如果用户从网页--》图片--》视频一下移动到音乐,只需要记录用户移动到了音乐即可。还有就是输入关键字非常快比如输入 菲律宾,实际查询菲律宾关键字就可以了。而不是输入“菲”查询一次“菲律”查询一次 “菲律宾”查询一次。
来一个最简单的例子,浏览器执行以下代码会发现console控制台输出很多次,但是计算资源是有限的,所以我们需要控制速度,这个好比游戏打怪,不等满血进度条完成,游戏无法开始。
上代码,看看防抖函数
经过上面的例子想必你也清楚了,什么是防抖,以及在前端如何防抖。对于后端那怎么防抖呢? 有兴趣的可以我在腾讯搜搜做积分系统的时候,写过的一篇文章,用memcache或者redis实际上实现的就是防抖
http://blog.sina.com.cn/s/blog_467eb8ca0100zmvb.html
那节流又是什么鬼东西呢??
函数节流
一个函数执行一次后,只有大于设定的执行周期后才会执行第二次。
节流函数,throttle(fun,delay)参数是1秒,则是不管持续多长时间,每秒执行一次,且每秒只执行一次。
这个打个比方,就是一盆水,慢慢流出来,而不是哐 一下直接倒了。这个很简单可以看示例中函数节流的那部分代码。
在上面那个?//函数节流
在服务器端实现函数节流就很简单了,最好是放在异步执行,用sleep函数定时执行即可。
关于防抖和节流的函数 ,都写在下面了,大家在输入框快速输入字母,然后打开浏览器控制台,自行测试。
函数防抖和函数节流都是防止某一时间频繁触发。
函数防抖是某一段时间内只执行最后一次,而函数节流是小间隔时间执行一次。
debounce 防抖?
window触发resize一次
滚动操作记录最终状态
鼠标不断点击触发,mousedown(单位时间内只触发一次)
输入参数校验,只需要校验一次就好
throttle 节流
search搜索联想,用户在不断输入值时,节约请求资源
监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
监听window 的resize多次
计算鼠标移动距离
canvas画图
射击游戏,单位时间点击按钮,单击鼠标发射一次子弹
?