我们先来通过代码把常见的问题还原:
<html> <head> <meta charset="utf-8"> <title>问题演示</title> </head> <body> <script type="text/javascript"> window.onload = function(){ // 没有处理防抖和节流的代码 let norInput = document.getElementById(‘normal‘); let ajax = content=>{ console.log(‘ajax:‘ + content); } norInput.addEventListener(‘keyup‘,e=>{ ajax(e.target.value) }) // console.log(debounce()()) } </script> <input type="text" name="normal" id="normal"> </body> </html>
在上面的程序中,看上去是没有什么问题,但是用户每输入一个字符,都会向后端发起一次请求,而这只是一个用户,如果同时很多用户进行相同的操作,无异于是给服务端造成极大的压力,所以,下文要说到的,就是关于JavaScript
当中的防抖
和节流
操作:
当用户在触发一次事件n秒后在执行回调函数,如果重复触发则进行重新计时。
根据防抖
的逻辑,下面通过代码来进行模拟:
<script type="text/javascript"> window.onload = function(){ let norInput = document.getElementById(‘normal‘); // 创建一个函数模拟ajax请求 let ajax = content=>{ console.log(‘ajax:‘ + content); } // 创建防抖函数 let debounce = (fn,delay) => { return function(args){ let that = this; let param = args; // 每次事件触发 清除当前的timmer 然后重写调用 clearTimeout(fn.id); fn.id = setTimeout(function(){ fn.call(that,param) },delay) } } let deb_func = debounce(ajax,500) norInput.addEventListener(‘keyup‘,e=>{ deb_func(e.target.value) }) } </script>
上面的demo
运行后,你会发下,用户如果停止输入后的一段时间才会发起ajax
请求,而如果用户持续输入,则计时器会不断的刷新,再这个过程中并不会发生请求,直到用户停止输入,才会开始计时,时间一到,才会发送请求。
这样就能够有效的减少因为频繁发送请求给服务器带来过大的压力。
设置一个时间范围,在一定的时间范围内,仅允许执行一次执行一次事件的回调函数,也就是说只要在规定时间范围内,无论事件触发几次,都只能执行一次回调函数。
我们通过click
事件来还原下事故现场:
<html> <head> <meta charset="utf-8"> <title>节流</title> </head> <body> <input type="button" id="btn" value="点击"> <script type="text/javascript"> let oBtn = document.getElementById(‘btn‘); let ajax = ()=>{ console.log("ajax发送请求") } oBtn.addEventListener(‘click‘,()=>{ ajax(); }) </script> </body> </html>
当用户每一次点击后,都会发送一次请求,点击不断,请求不断。如同生命不息,战斗不止
。可想而知,一旦有人无聊的一直点击,那么请求次数将会变得很可观。
下面是我们根据节流
的原理来实现的示例代码:
<html> <head> <meta charset="utf-8"> <title>问题演示</title> </head> <body> <script type="text/javascript"> window.onload = function(){ // 获取元素 let oBtn = document.getElementById(‘normal‘); // 模拟ajax请求 let ajax = ()=>{ console.log("ajax发送请求....") } // 节流函数 let throttle = (func,wait) =>{ var timeout ; var previous = 0; return function(){ var _this = this; args = arguments; if(!timeout){ timeout = setTimeout(function(){ timeout = null; func.apply(_this,args); },wait) } } } let thro_func = throttle(ajax,3000); // 绑定事件 oBtn.addEventListener(‘click‘,()=>{ thro_func(); }) } </script> <input type="button" name="normal" id="normal" value="点击"> </body> </html>
通过上面的案例,我们可以做到,当用户点击一次后,计时器开始,这当中无论发生几次事件触发,都仅仅会执行一次回调。
当然,想要实现节流的方法不止使用定时器这一种方案,还可以选择使用时间戳,再或者其他方法也不是不行,本文的目的仅仅是为了阐述和说明节流和防抖这两种减少服务器压力的方法而已。
原文:https://www.cnblogs.com/yuwenxiang/p/11700279.html