当前位置: 首页 > Web前端 > JavaScript

吃巧克力了解防抖和节流!再也不会忘记!

时间:2023-03-27 01:35:17 JavaScript

字并不陌生,但回过头来,我忘记了,我就是完全听不懂。先忘掉这两个字,进入一个新的情境吧~现在你是5岁的宝宝了,今天有小朋友来了,妈妈准备了很多巧克力。你看见了,连忙说,妈妈,我想吃巧克力,妈妈给了你一块,你又叽叽喳喳又给了我一块。你第三次唠叨的时候,妈妈不是很高兴。你已经吃了2块了,剩下的巧克力要等孩子们吃。作为一个5岁的宝宝,你很难接受,就一直在妈妈身后唠叨,“妈妈,我想吃巧克力,我真的很想吃巧克力”。妈妈被你气坏了,妥协说:“我定个半小时,到时候给你一块,如果你还想要,那我们再定一块。”计时半小时。”于是,妈妈定了一个半小时的定时器~可是你才5岁娃,还想吃东西,所以你还在后面唠叨,妈妈却不理你,还塞上了耳塞。半小时计时结束,计时响起,妈妈给你一块!吃完饭你又去唠叨了,妈妈就把定时器调了半个小时。Throttle好了,现在我们就根据上面的例子来说说你妈的攻略吧。你一直向你妈妈要巧克力。如果你要一次巧克力,妈妈会给你无数的巧克力。显然,你妈妈觉得很累。所以我妈妈拿了一个计时器。当你唠叨的时候,如果计时器还在计时,它就会不理你。如果计时器不计时,请重新开始计时。计时结束时给予一次。这大大降低了满意的频率。现在转换角色。你是一个开发者。网页上有一个查询按钮。每次点击都会请求接口,返回新的查询数据。但是一些用户(测试)可能会感到无聊并不断点击查询提交按钮。如果他们每秒点击十次,服务器将不得不返回数据十次。提交测试来找你,“老铁,控制频率,一秒发送一次请求。”这个时候节流。你不一定需要记住名词,但你只需要记住如何控制lettimes=0;constfn=console.log(`Sendrequest${++times}times`,newDate().toLocaleTimeString());//取一个定时器vartimer;/*点击这里相当于要巧克力*Every当你唠叨的时候,检查计时器是否在计时,*如果在计时,忽略它*如果不在计时,重新开始计时*当计时结束时,妈妈会主动给巧克力,然后转关闭定时器*/btn.onclick=()=>{//如果定时器还在计时,忽略它if(timer){return;}//如果定时器不在计时,重新开始计时timer=setTimeout(()=>{//定时器结束时,妈妈会主动给巧克力,然后关闭定时器fn();计时器=null;},1000);};throttling的一般版本用另一个函数生成下面的函数,这就变成了throttlingfunctionthrottle(fn,delay)的简短版本{//取一个定时器vartimer;return(...args)=>{//如果定时器还在计时,忽略它if(timer){return;}//如果定时器不在计时,重新开始计时timer=setTimeout(()=>{//当定时器结束时,妈妈主动给巧克力,然后关闭定时器fn(...args);timer=null;},延迟);};}btn.onclick=throttle(fn,1000);连续唠叨了两个小时,妈妈要洗脸,所以改变主意了~“这是定时器,你唠叨了,我就重新开始计时;定时器结束了,我再开始计时。”给你一块巧克力”你听着这种情况,赶紧闭嘴lettimes=0;constfn=console.log(`sendrequest${++times}times`,newDate().toLocaleTimeString());//拿一个计时器vartimer;/*点击这里相当于要巧克力*每次说话,定时器都会重新开始*定时器结束,妈妈会主动给巧克力*/btn.onclick=()=>{//随便说,重启定时器timer&&clearTimeout(timer);timer=setTimeout(()=>{//定时器结束,妈妈主动给巧克力,关闭定时器fn();timer=null},1000);};这个是防抖,说了就重启定时器,闭嘴一会,再给普通版的巧克力防抖。同理,用另外一个函数生成下面的函数,就变成了短版的防抖函数debounce(fn,delay){//带一个定时器vartimer=null;return(...args)=>{//只是打勾,重新计时定时器&&clearTimeout(timer);timer=setTimeout(()=>{//超时结束,妈妈主动给巧克力,关闭定时器fn(...args);timer=null},delay);};}btn.onclick=debounce(fn,1000);在上面的场景中,我想大家基本可以感受到两者的异同。原来的情况:只要会说话,就符合要求。缺点是:太常满足。现在用节流和防抖的话:节流就是用定时器。当你唠叨的时候,如果计时器还在计时,就忽略它;如果不在计数,则开始计数;结果是:你一直唠叨,明明每隔一段时间就可以满足要求。防抖是用定时器,当你唠叨的时候,它会重新计时;时间一到,你就主动满足要求。结果就是:你再唠叨,就说明达不到要求。只有当你停止唠叨时,要求过一段时间就会得到满足。同样的事情:拿一个定时器,当计时结束后,会主动满足要求。区别:在唠叨的时候,一定时间后满足要求,或者停止唠叨一定时间后满足要求。如何选择?其实你要选择哪一个,要看生意情况和你的心情!比如页面在滚动的时候,想实时的知道滚动的高度,但是这个实时不需要达到10毫秒的级别,那么想想50毫秒获取一次,也就是,页面滚动时,你想每隔50ms获取一次,显然是在节流~如果你只想在页面停止滚动时才获取,那显然是防抖~滚动可以类比,一直唠叨chocolate,而获取页面的高度就相当于满足了chocolateYou~如果你没有特殊需求,只想控制获取的个数,那你就开心了~~常见场景:当用户滚动页面时点击按钮发送请求理解为防止你的嘴唇不停地颤抖。只有当你停止摇晃时,你才会在一段时间后感到满意。一知防抖,一知节流。如何实际使用它?虽然简化版可以满足一些场景,但是一般不建议使用自己手写的。你知道这样的逻辑会起作用。在实际使用中,直接使用库包是比较安全的。以lodash为例://npmilodash或https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.jsbtn.onclick=_.throttle(fn,1000);btn.onclick=_.debounce(fn,1000);这里多了两个参数:leading,表示计时开始前是否给你巧克力,默认为false,即计时开始前没有巧克力trailing,表示计时结束后是否给你巧克力,默认为true,即在计时结束时给出chocolate的两个参数。根据使用场景,文中示例为默认情况。javascript