js函数的节流与防抖,web前端常见面试题解析之函

节流与防抖这两个词汇在面试的过程当中出现的频率是非常之高的!首先你要知道节流与防抖它并不是一门什么新的技术,而是为解决某些问题所采取的一种程序手段而已。再说直白一些其所指的就是代码优化!那么它们要解决的问题是什么?用于解决用户频繁触发事件执行,而对DOM操作、资源加载等耗费性能的问题。该问题可能会导致界面卡顿,甚至浏览器崩溃,从而降低你的用户体验!

一、防抖&节流

  在前端开发中有一部分用户行为会频繁的触发事件执行,而对于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 }  

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

    图片 1

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

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

    效果图如下:

    图片 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)

    效果图如下:

图片 3

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

  

  2.防抖

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

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

    2.1).案例(实时搜索)

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

图片 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;

      效果图如下:

图片 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后发出请求

      效果图:图片 6

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

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

 

    

    

    

我们先来聊一聊函数节流究竟是个什么鬼?先来看下定义:

  • 函数节流指的是预定一个函数,只有函数在大于等于执行周期时才执行,周期内调用不执行。

我们可以将这个定义进行一下拆分:1、所谓函数节流指的就是一个函数。2、该函数的执行需要一个周期进行控制。3、周期内调用该函数不执行,否则会执行。

拆分完之后你会发现,要想理解函数节流的重点便是周期二字。

周期即时间,在指定的时间内不会执行,超过了便执行。就拿生孩子来讲,需要十月怀胎,总不会一个月就生个宝宝出来吧!即使你能创造人类生育史的奇迹,一个月生个健康的宝宝,可一个月也是一个周期对吧!如果到现在你还感觉不太好理解,那么咱们来完成一个小例子,每点击一次按钮数字加1,如图:

图片 7

<body> <div>0</div> <input type="button" value="点我啊" /> <script> var myShow = document.querySelector; var myBtn = document.querySelector; myBtn.onclick = function  { myShow.innerText = parseInt(myShow.innerText)+1; } </script></body>

上面的代码很简单,它告诉我们,只要你速度够快,点击多少次事件便会执行多少次!你发疯的点击,数字便会发疯的增长!虽然你点的很爽,但是代码这样写是有问题的!如果你的DOM渲染比较复杂的话定会造成性能的浪费,另外如果有人恶意攻击的话,后果也是比较严重的,比如我可以在控制台写以下代码:

图片 8

你会发现数字变了,这肯定不是你想看到的!但这就是现实!如果你做的是商品抢购活动的话,是不是瞬间就木有啦?还好我比较仁慈,写的循环次数比较小(如果你再往后面加上几个9的话,你的浏览器结果只有死路一条!不妨亲爱的你可以试试看!),如果脚本多执行几次呢?现在走到这一步,程序便需要优化了。聪明的你可能会想:如果我给他加上一些时间的限制,让其在指定的时间内不允许触发事件,一切不都迎刃而解了吗?没错,这就是函数节流的核心思想!js代码优化如下:

<script> var myShow = document.querySelector; var myBtn = document.querySelector; /* 定义的节流函数 func指定的时间结束后所执行的函数, wait指定的时间 返回值为函数 */ function throttle(func, wait) { let previous = 0; return function() { let now = Date.now(); let context = this; if (now - previous >= wait) { func.apply(context, arguments); // 函数执行后更新 previous 值 previous = now; } } } function addOne() { myShow.innerText = parseInt(myShow.innerText)+1; } myBtn.onclick = throttle(addOne,1000);</script>

程序运行,一切还是那么美好!以上代码用到的throttle函数,便是通过闭包封装的节流函数,其核心就是:让一个函数不要执行得太频繁,减少一些过快的调用来节流。未完,后面再来聊一聊防抖!价值400元的前端电子书,总有一本适合你!别客气,赶紧拿走拿走!!

本文由365bet体育在线官网发布于网络工程,转载请注明出处:js函数的节流与防抖,web前端常见面试题解析之函

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。