JS函数节流和函数防抖问题分析

问题1:如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办?

**问题2:**如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生?

为了应对如上场景,便出现了 函数防抖 和 函数节流 两个概念,总的来说:

这两个方法是在 时间轴上控制函数的执行次数。

函数防抖(debounce)

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

生活中的实例: 如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。

函数节流(throttle)

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

生活中的实例: 我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。

分析图

假设,我们观察的总时间为10秒钟,规定1秒作为一次事件的最小间隔时间。

如果触发事件的频率是 0.5s/次 ,那么函数防抖如图

因为始终没法等一秒钟就被再次触发了,所以最终没有一次事件是成功的。

函数节流如图

因为控制了最多一秒一次,频率为 0.5s/次 ,所以每一秒钟就有一次事件作废。最终控制成 1s/次

如果触发事件的频率是 2s/次 ,那么

函数防抖如图

因为 2s/次
已经大于了规定的最小时间,所以每计时两秒便触发一次。

函数节流如图

同样, 2s/次 大于了最小时间规定,所以每一次触发都生效。

应用场景

对于函数防抖,有以下几种应用场景:

  • 给按钮加函数防抖防止表单多次提交。
  • 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
  • 判断 scroll 是否滑到底部, 滚动事件 + 函数防抖

总的来说,适合多次事件 一次响应 的情况

对于函数节流,有如下几个场景:

  • 游戏中的刷新率
  • DOM元素拖拽
  • Canvas画笔功能

总的来说,适合 大量事件 按时间做 平均 分配触发。

源码

函数防抖:

function debounce(fn, wait) {
 var timer = null;
 return function () {
  var context = this
  var args = arguments
  if (timer) {
   clearTimeout(timer);
   timer = null;
  }
  timer = setTimeout(function () {
   fn.apply(context, args)
  }, wait)
 }
}
var fn = function () {
 console.log('boom')
}
setInterval(debounce(fn,500),1000) // 第一次在1500ms后触发,之后每1000ms触发一次
setInterval(debounce(fn,2000),1000) // 不会触发一次(我把函数防抖看出技能读条,如果读条没完成就用技能,便会失败而且重新读条)

之所以返回一个函数,因为防抖本身更像是一个函数修饰,所以就做了一次函数柯里化。里面也用到了闭包,闭包的变量是 timer 。

函数节流

function throttle(fn, gapTime) {
 let _lastTime = null;
 return function () {
 let _nowTime = + new Date()
 if (_nowTime - _lastTime > gapTime || !_lastTime) {
  fn();
  _lastTime = _nowTime
 }
 }
}
let fn = ()=>{
 console.log('boom')
}
setInterval(throttle(fn,1000),10)

如图是实现的一个简单的函数节流,结果是 一秒打出一次boom

总结

以上所述是小编给大家介绍的JS函数节流和函数防抖问题分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • javascript函数的节流[throttle]与防抖[debounce]

    防抖和节流 窗口的resize.scroll,输入框内容校验等操作时,如果这些操作处理函数较为复杂或页面频繁重渲染等操作时,如果事件触发的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕.此时我们可以采用debounce(防抖)和throttle(节流)的方式来减少触发的频率,同时又不影响实际效果. 这两个东西都是为了项目优化而出现的,官方是没有具体定义的,他们的出现主要是为了解决一些短时间内连续执行的事件带来性能上的不佳和内存的消耗巨大等问题: 像这类事件一般像 scroll keyup

  • 浅谈JS函数节流防抖

    在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作.资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃.函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的. 函数节流(throttle) 函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行.好像水滴攒到一定重量才会落下一样. 场景: 窗口调整(resize) 页面滚动(scroll) 抢购疯狂点击(mousedown) 实现: function thrott

  • JavaScript函数节流和函数防抖之间的区别

    一.概念解释 函数节流和函数防抖,两者都是优化高频率执行js代码的一种手段. 大家大概都知道旧款电视机的工作原理,就是一行行得扫描出色彩到屏幕上,然后组成一张张图片.由于肉眼只能分辨出一定频率的变化,当高频率的扫描,人类是感觉不出来的.反而形成一种视觉效果,就是一张图.就像高速旋转的风扇,你看不到扇叶,只看到了一个圆一样. 同理,可以类推到js代码.在一定时间内,代码执行的次数不一定要非常多.达到一定频率就足够了.因为跑得越多,带来的效果也是一样.倒不如,把js代码的执行次数控制在合理的范围.既

  • JS函数节流和函数防抖问题分析

    问题1:如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办? **问题2:**如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生? 为了应对如上场景,便出现了 函数防抖 和 函数节流 两个概念,总的来说: 这两个方法是在 时间轴上控制函数的执行次数. 函数防抖(debounce) 概念: 在事件被触发n秒后再执行回调,如果在这n秒内

  • JavaScript函数节流和函数去抖知识点学习

    概念 节流 (throttle) 让一个函数不要执行的太频繁,减少执行过快的调用,叫节流 去抖 (debounce) 去抖就是对于一定时间段的连续的函数调用,只让其执行一次 throttle 应用场景 DOM 元素的拖拽功能实现(mousemove) 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹) 计算鼠标移动的距离(mousemove) Canvas 模拟画板功能(mousemove 搜索联想(keyup 监听滚动事件判断是否到页面底部自动加载更多:给 scr

  • JavaScript函数防抖与函数节流的定义及使用详解

    目录 一.函数防抖(Debouncing) 1.基本概念 2.算法思想 3.代码实现 4.使用场景 二.函数节流(Throlle) 1.基本概念 2.算法思想 3.代码实现 4.使用场景 一.函数防抖(Debouncing) 1.基本概念 在触发事件后的规定时间内只能执行一次,如果在规定时间内又触发了该事件.则会重新开始计算规定时间: 2.算法思想 (1)首先定义一个函数,函数进入页面立即执行一次,且永远执行最新的一次: (2)返回一个匿名函数: (3)在匿名函数里使用计时器setTimeout

  • JS中setTimeout的巧妙用法前端函数节流

    什么是函数节流? 函数节流简单的来说就是不想让该函数在很短的时间内连续被调用,比如我们最常见的是窗口缩放的时候,经常会执行一些其他的操作函数,比如发一个ajax请求等等事情,那么这时候窗口缩放的时候,有可能连续发多个请求,这并不是我们想要的,或者是说我们常见的鼠标移入移出tab切换效果,有时候连续且移动的很快的时候,会有闪烁的效果,这时候我们就可以使用函数节流来操作.大家都知道,DOM的操作会很消耗或影响性能的,如果是说在窗口缩放的时候,为元素绑定大量的dom操作的话,会引发大量的连续计算,比如

  • 微信小程序防止多次点击跳转(函数节流)

    场景 在使用小程序的时候会出现这样一种情况:当网络条件差或卡顿的情况下,使用者会认为点击无效而进行多次点击,最后出现多次跳转页面的情况,就像下图(快速点击了两次): 解决办法 然后从 轻松理解JS函数节流和函数防抖 中找到了解决办法,就是函数节流(throttle):函数在一段时间内多次触发只会执行第一次,在这段时间结束前,不管触发多少次也不会执行函数. /utils/util.js: function throttle(fn, gapTime) { if (gapTime == null ||

  • JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)

    函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我触发一个时间时,先setTimout让这个事件延迟一会再执行,如果在这个时间间隔内又触发了事件,那我们就clear掉原来的定时器,再setTimeout一个新的定时器延迟一会执行,就这样. 以下场景往往由于事件频繁被触发,因而频繁执行DOM操作.资源加载等重行为,导致UI停顿甚至浏览器崩溃. 1.

  • JS函数节流和防抖之间的区分和实现详解

    在写JS时,这两个函数比较常见,有时候傻傻分不清用哪个,或者说知道代码要怎么写,但要说出它究竟是节流函数还是防抖函数时一脸楞逼.今天有一个同学分享了这两个的区分,我也来回顾一下,加深一下印象,以便日后用到时心里有底.PS:百度和谷歌搜索前几个介绍都是相反介绍,本文为原创,如有雷同纯属抄袭我的. 节流概念(Throttle) 按照设定的时间固定执行一次函数,比如200ms一次.注意:固定就是你在mousemove过程中,执行这个节流函数,它一定是200ms(你设定的定时器延迟时间)内执行一次.没到

  • 如何理解JS函数防抖和函数节流

    概述 函数防抖和函数节流都是定义一个函数,该函数接收一个函数作为参数,并返回一个添加了防抖或节流功能后的函数. 因此可以将函数防抖和函数节流看作是一个函数工厂,负责对传进来的函数进行相应的加工改造,然后产出一个新的带有某种功能的函数. 函数防抖是某一时间内只执行一次,而函数节流是间隔时间执行 假如有这样一个场景:在某一页面,有一个按钮是 "加载更多",这个按钮的作用就是使用 ajax 从后端服务器请求更多的数据展示在页面,我们都知道,ajax 请求的响应是一个异步的,会存在一定的响应时

随机推荐