JavaScript防抖和节流

问题还原

我们先来通过代码把常见的问题还原:

<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秒后在执行回调函数,如果重复触发则进行重新计时。

根据防抖的逻辑,下面通过代码来进行模拟:

<html>
<head>
<meta charset="utf-8">
<title>问题演示</title>
</head>
<body> <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> <input type="text" name="normal" id="normal"> </body>
</html>

上面的demo运行后,你会发下,用户如果停止输入后的一段时间才会发起ajax请求,而如果用户持续输入,则计时器会不断的刷新,再这个过程中并不会发生请求,直到用户停止输入,才会开始计时,时间一到,才会发送请求。

这样就能够有效的减少因为频繁发送请求给服务器带来过大的压力。

使用场景

  1. resize 事件或者scroll事件等,可以通过防抖减少触发次数
  2. 用户在输入框中频繁输入

节流

什么是节流

设置一个时间范围,在一定的时间范围内,仅允许执行一次执行一次事件的回调函数,也就是说只要在规定时间范围内,无论事件触发几次,都只能执行一次回调函数。

我们通过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>

通过上面的案例,我们可以做到,当用户点击一次后,计时器开始,这当中无论发生几次事件触发,都仅仅会执行一次回调。

当然,想要实现节流的方法不止使用定时器这一种方案,还可以选择使用时间戳,再或者其他方法也不是不行,本文的目的仅仅是为了阐述和说明节流防抖这两种减少服务器压力的方法而已。

使用场景

  1. 鼠标不断点击的情况
  2. 页面无限加载,每隔一段时间发起请求而不是用户停止滚动发起请求
  3. ...

来聊聊JavaScript中的防抖和节流的更多相关文章

  1. JavaScript 中的防抖和节流

    什么是防抖 函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时.如下图,持续触发 scrol ...

  2. JavaScript中函数防抖、节流

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14565642.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  3. 直播开始:'云榨汁机'诞生记--聊聊JavaScript中的'业务建模'

    闭包是JavaScript中的一个重要特性,在之前的博文中,我们说闭包是一个'看似简单,其实很有内涵'的特性.当我们用JavaScript来实现相对复杂的业务建模时,我们可以如何利用'闭包'这个特性呢 ...

  4. JS中的防抖与节流

    什么是防抖?and什么是节流?一起来开心的学习下吧. 首先什么是防抖:就是在一定的时间内事件只发生一次,比如你点击button按钮,1秒内任你单身30年手速点击无数次,他也还是只触发一次.举个例子,当 ...

  5. Js中的防抖与节流函数

    1.何为防抖与节流函数呢? 1.防抖(debounce):通过setTimeout方式,在一定的时间间隔内,将多次触发的事件转化为一次触发.也就是说当一个用户一直触发这个函数,且每次触发函数的间隔小于 ...

  6. 面试说:聊聊JavaScript中的数据类型

    前言 请讲下 JavaScript 中的数据类型? 前端面试中,估计大家都被这么问过. 答:Javascript 中的数据类型包括原始类型和引用类型.其中原始类型包括 null.undefined.b ...

  7. JS中的防抖和节流

    JS-防抖和节流 在进行窗口的resize.scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕.此时我们可以采用debounce(防抖)和 ...

  8. 聊聊Javascript中的AOP编程

    Duck punch 我们先不谈AOP编程,先从duck punch编程谈起. 如果你去wikipedia中查找duck punch,你查阅到的应该是monkey patch这个词条.根据解释,Mon ...

  9. JavaScript函数的防抖和节流

    防抖 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间 思路: 每次触发事件时都取消之前的延时调用方法 function debounce(fn) { let tim ...

随机推荐

  1. 再度吐槽,PHP在centos7的安装方式稍不注意可能就打击你的积极性

    由于装新机器,没仔细看随便找了篇博文就匆匆安装了php73结果,连配置文件,扩展模块都找不着在哪这里介绍一个linux的查找命令 find / -name php73* 这一命令使用了*这一正则匹配的 ...

  2. Jquery 前端解码base64出现中文乱码的问题解决方案

    <script src="../static/js/jquery.base64.js"></script> <script src="../ ...

  3. Lighting Techinology of the Last Of Us (2013 SIGGRAPH)

    Lighting Techinology of the Last Of Us(2013 SIGGRAPH) or "Old Lightmaps - New Tricks" 原作:M ...

  4. jmeter请求参数中文乱码,解决方法

  5. Luogu P2324 [SCOI2005]骑士精神 搜索

    刚开始写了个没迭代的...结果过了$qwq$ 然后迭个代..更快了.. #include<cstdio> #include<iostream> #define R regist ...

  6. mysql日常优化细节

    # sql语句优化> 1)使用limit限制一次性查询出的数据量2)链接查询代替子查询3)尽量不要使用select * ,将需要查找的字段列出来4)如果数据量特别大的话尽量将一条复杂的sql拆分 ...

  7. [Luogu] 文艺平衡树(Splay)

    题面:https://www.luogu.org/problemnew/show/P3391 题解:https://www.zybuluo.com/wsndy-xx/note/1138892

  8. Python中的函数递归思想,以及对比迭代和递归解决Fibonacci数列

    什么是递归?简单的说就是:函数自身调用自身. “普通程序员用迭代,天才程序员用递归” 虽然递归 在运行时会不断出栈压栈,调用底层的寄存器,造成空间上的占用以及时间上的缓慢, 但在一些算法上面仍然是递归 ...

  9. Jmeter(十三)阶梯式压测

    阶梯式压测,就是对系统的压力呈现阶梯性增加的过程,每个阶段压力值都要增加一个数量值,最终达到一个预期值.然后保持该压力值,持续运行一段时间. Jmeter中有个插件可以实现这个场景,这个插件就是:Co ...

  10. Codeforces 1205C Palindromic Paths (交互题、DP)

    题目链接 http://codeforces.com/contest/1205/problem/C 题解 菜鸡永远做着变巨的梦 然而依然连div1BC题都不会做 要是那天去打cf怕是又要1题滚粗了.. ...