直接刷了一百多盒月饼,去执行一个异步请求时

作者: 前端  发布:2019-12-09

一、防抖&节流

  在前端开发中有一部分用户行为会频繁的触发事件执行,而对于DOM的操作、资源加载等耗费性能的处理,很可能会导致界面卡顿,甚至浏览器奔溃。函数的节流与防抖就是为了解决类似需求而产生的。

  1)节流

    概念:函数的节流就是预定一个函数只有在大于等于执行周期时才会执行,周期内调用不会执行。好像一滴水只有积攒到一定重量才会落下一样。

    场景:窗口调整(resize)、页面滚动(scroll)、抢购疯狂点击(movedown)

    故事:阿里巴巴月饼门事件,中秋来临,阿里特意做了一个活动,抢月饼,但是每个人只能抢购一盒,有五位工程师写了js脚本,类似于12306的抢票软件,直接刷了一百多盒月饼,结果被开除了四个.其实对于他们来说并不是什么坏事,不知道有多少公司对他们敞开大门~那么如何解决这种问题呢,就用到了函数的节流

  1.1)案例(限时抢购)

    我写了这样一个简单的事件,如下

HTML:
1 <button id='show'>抢购</button>
2 <div id="box">0</div>  

JS:
1 let oBtn=document.getElementById('show')
2 let oBox=document.getElementById('box')
3 oBtn.onclick=function(){
4   oBox.innerText=parseInt(oBox.innerText)+1
5 }  

    当我点击时,每点击一次,数量增加一,点击越快,增加越快,效果图如下:

    9159.com 1

  1.2)脚本攻击:这种简单的数量增加很容易遭到脚本的攻击,从而造成很大的损失。代码如下

    for(let i=0;i<100;i++){oBtn.click()}

    效果图如下:

    9159.com 2

  1.3)如何解决(节流)

    上面并不是我们想要的结果,我们想要的是在规定时间内只能执行一次,比如1秒内只能执行一次.无论你点击多少次.

HTML:
1 <button id='show'>抢购</button>
2 <div id="box">0</div>

 JS:
 1 let oBtn=document.getElementById('show');
 2     let oBox=document.getElementById('box');
 3     /*
 4         handle:buy函数
 5         wait:规定在一秒钟内只能执行一次
 6     */
 7     function throttle (handle, wait) {
 8         let lastTime = 0;
 9         return function (e) {
10             let nowTime = new Date().getTime()
11             if (nowTime - lastTime > wait) {
12                 handle();
13                 lastTime = nowTime;
14             }
15         }
16     }
17     function buy(){
18         oBox.innerText = parseInt(oBox.innerText)+1
19     }
20     oBtn.onclick = throttle(buy, 1000)

    效果图如下:

9159.com 3

    这样不仅可以达到想要的效果,还可以阻止恶意脚本的攻击.

  

  2.防抖

    概念:函数防抖就是函数需要频繁触发情况时,只有足够空闲的时候,才会执行一次。好像公交司机会等人都上车后才会开车一样.

    场景:实时搜索(keyup)、拖拽(mousemove)

    2.1).案例(实时搜索)

      在之前看一下这个过程图,百度的实时搜索.

9159.com 4

 

      在搜索nba的时候,并不是每输入一个字符,都会想服务器请求一次,而是在输入完成后发出一次请求。

HTML:
1 <input type='text' id='ipt'/>

JS:
1 let oIpt = document.getElementById('ipt');
2 function ajax () {
3     console.log(this.value)
4 }
5 oIpt.oninput = ajax;

9159.com ,      效果图如下:

9159.com 5

    用户无论输入多快,都会发出请求,从而去加载服务器资源,对性能有很大的影响.

    2.3)解决(防抖)

 1 let oIpt = document.getElementById('ipt');
 2     let time = null;
 3     function debounce (handle, delay) {
 4         let time = null;
 5         return function () {
 6             let self = this,arg = arguments;
 7             clearTimeout(time);
 8             time = setTimeout(function () {
 9                 handle.apply(self,arg);  //this绑定
10             },delay)
11         }
12     }
13     function ajax (e) {
14         console.log(e,this.value)
15     }
16     oIpt.oninput = debounce(ajax, 1000)  //1s后发出请求

      效果图:9159.com 6

  这种方法可以解决多次请求的问题,对性能有很大的提高。

  喜欢的小伙伴点个关注哦~我会再接再厉的。

 

    

    

    

前言:

我们在做页面事件绑定的时候,经常要进行节流处理,比如鼠标异步点击,去执行一个异步请求时,需要让它在上一次没执行时不能再点击,又或者绑定滚动事件,这种持续触发进行dom判断的时候,就要按一定频率的执行。

本文主要给大家介绍了关于js防抖和节流的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

0. 引入

模拟在输入框输入后做ajax查询请求,没有加入防抖和节流的效果,这里附上完整可执行代码:

 没有防抖   window.onload = function () { //&#27169;&#25311;ajax&#35831;&#27714; function ajax { console.log('ajax request ' + content) } let inputNormal = document.getElementById; inputNormal.addEventListener { ajax }   1.没有防抖的输入:  

效果:在输入框里输入一个,就会触发一次“ajax请求”。

缺点:浪费请求资源,可以加入防抖和节流来优化一下。

本文会分别介绍什么是防抖和节流,它们的应用场景,和实现方式。防抖和节流都是为了解决短时间内大量触发某函数而导致的性能问题,比如触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。但二者应对的业务需求不一样,所以实现的原理也不一样,下面具体来看看吧。

1. 防抖

1.1 什么是防抖

在事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时。

1.2 应用场景

用户在输入框中连续输入一串字符后,只会在输入完后去执行最后一次的查询ajax请求,这样可以有效减少请求次数,节约请求资源;

window的resize、scroll事件,不断地调整浏览器的窗口大小、或者滚动时会触发对应事件,防抖让其只触发一次;

1.3 实现

还是上述列子,这里加入防抖来优化一下,完整代码如下:

 加入防抖   window.onload = function () { //&#27169;&#25311;ajax&#35831;&#27714; function ajax { console.log('ajax request ' + content) } function debounce { return function  { //&#33719;&#21462;&#20989;&#25968;&#30340;&#20316;&#29992;&#22495;&#21644;&#21464;&#37327; let that = this let _args = args //&#27599;&#27425;&#20107;&#20214;&#34987;&#35302;&#21457;&#65292;&#37117;&#20250;&#28165;&#38500;&#24403;&#21069;&#30340;timeer&#65292;&#28982;&#21518;&#37325;&#20889;&#35774;&#32622;&#36229;&#26102;&#35843;&#29992; clearTimeout fun.id = setTimeout { fun.call }, delay) } } let inputDebounce = document.getElementById let debounceAjax = debounce inputDebounce.addEventListener { debounceAjax }   2.加入防抖后的输入:  

代码说明:

1.每一次事件被触发,都会清除当前的 timer 然后重新设置超时调用,即重新计时。 这就会导致每一次高频事件都会取消前一次的超时调用,导致事件处理程序不能被触发;

2.只有当高频事件停止,最后一次事件触发的超时调用才能在delay时间后执行;

效果:

加入防抖后,当持续在输入框里输入时,并不会发送请求,只有当在指定时间间隔内没有再输入时,才会发送请求。如果先停止输入,但是在指定间隔内又输入,会重新触发计时。

2.节流

2.1 什么是节流

规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。

2.2 应用场景

,只在单位时间内只触发一次;

在页面的无限加载场景下,需要用户在滚动页面时,每隔一段时间发一次 ajax 请求,而不是在用户停下滚动页面操作时才去请求数据;

监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断;

2.3 实现

还是上述列子,这里加入节流来优化一下,完整代码如下:

 加入节流   window.onload = function () { //&#27169;&#25311;ajax&#35831;&#27714; function ajax { console.log('ajax request ' + content) } function throttle { let last, deferTimer return function  { let that = this; let _args = arguments; let now = +new Date(); if (last &amp;&amp; now &lt; last + delay) { clearTimeout; deferTimer = setTimeout { last = now; fun.apply; }, delay) } else { last = now; fun.apply; } } } let throttleAjax = throttle let inputThrottle = document.getElementById inputThrottle.addEventListener { throttleAjax }   3.加入节流后的输入:  

效果:实验可发现在持续输入时,会安装代码中的设定,每1秒执行一次ajax请求

3. 小结

总结下防抖和节流的区别:

-- 效果:

函数防抖是某一段时间内只执行一次;而函数节流是间隔时间执行,不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。

-- 原理:

防抖是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,都会清除当前的 timer 然后重新设置超时调用,即重新计时。这样一来,只有最后一次操作能被触发。

节流是通过判断是否到达一定时间来触发函数,若没到规定时间则使用计时器延后,而下一次事件则会重新设定计时器。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

本文由9159.com发布于前端,转载请注明出处:直接刷了一百多盒月饼,去执行一个异步请求时

关键词: