javascript的防抖节流函数解析

目录
  • 防抖节流函数的解析
    • 认识防抖和节流函数
    • 认识防抖debounce函数
    • 防抖函数的案例
    • 认识节流throttle函数
    • 节流函数的应用场景
    • 自定义防抖和节流函数
  • 总结

防抖节流函数的解析

认识防抖和节流函数

防抖和节流的概念其实最早并不是出现在软件工程中,防抖是出现在电子元件中,节流出现在流体流动中

  • 而JavaScript是事件驱动的,大量的操作会触发事件,加入到事件队列中处理。
  • 而对于某些频繁的事件处理会造成性能的损耗,我们就可以通过防抖和节流来限制事件频繁的发生;

防抖和节流函数目前已经是前端实际开发中两个非常重要的函数,也是面试经常被问到的面试题

但是很多前端开发者面对这两个功能,有点摸不着头脑:

  • 某些开发者根本无法区分防抖和节流有什么区别(面试经常会被问到);
  • 某些开发者可以区分,但是不知道如何应用;
  • 某些开发者会通过一些第三方库来使用,但是不知道内部原理,更不会编写;

认识防抖debounce函数

我们用一副图来理解一下它的过程:

  • 当事件触发时,相应的函数并不会立即触发,而是会等待一定的时间;
  • 当事件密集触发时,函数的触发会被频繁的推迟;
  • 只有等待了一段时间也没有事件触发,才会真正的执行响应函数;

防抖的应用场景很多:

  • 输入框中频繁的输入内容,搜索或者提交信息;
  • 频繁的点击按钮,触发某个事件;
  • 监听浏览器滚动事件,完成某些特定操作;
  • 用户缩放浏览器的resize事件;

防抖函数的案例

我们都遇到过这样的场景,在某个搜索框中输入自己想要搜索的内容

比如想要搜索一个MacBook:

  • 当我输入m时,为了更好的用户体验,通常会出现对应的联想内容,这些联想内容通常是保存在服务器的,所以需要一次网络请求;
  • 当继续输入ma时,再次发送网络请求;
  • 那么macbook一共需要发送7次网络请求;
  • 这大大损耗我们整个系统的性能,无论是前端的事件处理,还是对于服务器的压力;

但是我们需要这么多次的网络请求吗?

  • 不需要,正确的做法应该是在合适的情况下再发送网络请求;
  • 比如如果用户快速的输入一个macbook,那么只是发送一次网络请求;
  • 比如如果用户是输入一个m想了一会儿,这个时候m确实应该发送一次网络请求;
  • 也就是我们应该监听用户在某个时间,比如500ms内,没有再次触发时间时,再发送网络请求;

这就是防抖的操作:只有在某个时间内,没有再次触发某个函数时,才真正的调用这个函数;

认识节流throttle函数

我们用一副图来理解一下节流的过程

  • 当事件触发时,会执行这个事件的响应函数;
  • 如果这个事件会被频繁触发,那么节流函数会按照一定的频率来执行函数;
  • 不管在这个中间有多少次触发这个事件,执行函数的频繁总是固定的;

节流的应用场景:

  • 监听页面的滚动事件;
  • 鼠标移动事件;
  • 用户频繁点击按钮操作;
  • 游戏中的一些设计;

节流函数的应用场景

很多人都玩过类似于飞机大战的游戏

在飞机大战的游戏中,我们按下空格会发射一个子弹:

  • 很多飞机大战的游戏中会有这样的设定,即使按下的频率非常快,子弹也会保持一定的频率来发射;
  • 比如1秒钟只能发射一次,即使用户在这1秒钟按下了10次,子弹会保持发射一颗的频率来发射;
  • 但是事件是触发了10次的,响应的函数只触发了一次;

自定义防抖和节流函数

我们按照如下思路来实现:

防抖基本功能实现:可以实现防抖效果

  • 优化一:优化参数和this指向
  • 优化二:优化取消操作(增加取消功能)
  • 优化三:优化立即执行效果(第一次立即执行)
  • 优化四:优化返回值
function debounce(fn,delay,immediate=false,resultCallback){
  let timer=null
  // console.log(this)//window
  // 定义控制立即执行的变量,false表示没有执行过
  let isInvoke=false
  // 真正的处理函数
  function _debounce(...args){
    // 取消事件执行操作
    if(timer) clearTimeout(timer)
    // console.log(this)//element元素
    if(immediate&&!isInvoke){
      const result=fn.apply(this,args)
      resultCallback(result)
      isInvoke=true
    }else{
      // 延迟执行
      timer=setTimeout(()=>{
        const result=fn.apply(this,args)
        resultCallback(result)
        timer=null
        isInvoke=false
      },delay)
    }
  }
  // 封装取消请求
  _debounce.cancel=function(){
    if(timer) clearTimeout(timer)
    timer=null
    isInvoke=false
  }
  return _debounce
}

我们按照如下思路来实现:

节流函数的基本实现:可以实现节流效果

  • 优化一:节流最后一次也可以执行
  • 优化二:优化添加取消功能
  • 优化三:优化返回值问题
function throttle(fn,interval,options={leading:true,trailing:false}){
  let lastTime=0
  const {leading,trailing,resultCallback}=options
  let timer=null
  function _throttle(...args){
    const nowTime=new Date().getTime()
    // leading优化
    if(!leading&&!lastTime) lastTime=nowTime
    let remainTime=interval-(nowTime-lastTime)
    if(remainTime<=0){
      if(timer){
        clearTimeout(timer)
        timer=null
      }
      // 参数优化
      const result=fn.apply(this,args)
      if(resultCallback) resultCallback(result)
      lastTime=nowTime
      return
    }
    // 优化trailing
    if(!timer&&trailing){
      timer=setTimeout(()=>{
        // 参数优化
        const result=fn.apply(this,args)
        if(resultCallback) resultCallback(result)
        timer=null
        lastTime=!leading?0:new Date().getTime()
      },remainTime)
    }
  }
  _throttle.cancel=function(){
    if(timer) clearTimeout(timer)
    timer = null
    lastTime = 0
  }
  return _throttle
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 浅析JavaScript 函数防抖和节流

    函数防抖和节流都是对高频动作触发回调函数的一个优化,实现方式上有类似之处.先从使用场景做个区分. 防抖使用场景: 表单输入框校验 提交按钮避免重复提交 节流使用场景: scroll,mousemove,resize等 函数防抖(debounce) 表单输入框校验在用户不停的打字输入时并不需要向后台校验文本,只有当用户停下来一定时间后,这时候默认用户已经输入完毕了可以开始向后台提交文本了. 表单的提交按钮被用户多次连续点击时,显然并不需要每次点击都提交表单.仅在用户不点击之后,把最后一次的点击操作

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

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

  • 如何在面试中手写出javascript节流和防抖函数

    面试的时候我们经常会问别人是理解什么是节流和防抖,严格的可能要求你写出节流和防抖函数,这里我们抛开loadsh工具库手写节流和防抖 1.节流函数throttle // 节流方案1,每delay的时间执行一次,通过开关控制 function throttle(fn, delay, ctx) { let isAvail = true return function () { let args = arguments // 开关打开时,执行任务 if (isAvail) { fn.apply(ctx,

  • 浅谈JavaScript节流和防抖函数

    概念 节流函数 间隔固定的时间执行传入的方法 目的是防止函数执行的频率过快,影响性能.常见于跟滚动,鼠标移动事件绑定的功能. 防抖函数 对于接触过硬件的人也许更好理解,硬件按钮按下时,由于用户按住时间的长短不一,会多次触发电流的波动,加一个防抖函数就会只触发一次,防止了无意义的电流波动引起的问题. 按键防反跳(Debounce)为什么要去抖动呢?机械按键在按下时,并非按下就接触的很好,尤其是有簧片的机械开关,会在接触的瞬间反复的开合多次,直到开关状态完全改变. 应用在前端时,常见的场景是,输入框

  • Javascript节流函数throttle和防抖函数debounce

    问题的引出 在一些场景往往由于事件频繁被触发,因而频繁地进行DOM操作.资源加载,导致UI停顿甚至浏览器崩溃. 在这样的情况下,我们实际上的需求大多为停止改变大小n毫秒后执行后续处理:而其他事件大多的需求是以一定的频率执行后续处理.针对这两种需求就出现了debounce和throttle两种解决办法. 1. resize事件 2. mousemove事件 3. touchmove事件 4.scroll事件 throttle 与 debounce 在现在很多的javascript框架中都提供了这两

  • javascript的防抖节流函数解析

    目录 防抖节流函数的解析 认识防抖和节流函数 认识防抖debounce函数 防抖函数的案例 认识节流throttle函数 节流函数的应用场景 自定义防抖和节流函数 总结 防抖节流函数的解析 认识防抖和节流函数 防抖和节流的概念其实最早并不是出现在软件工程中,防抖是出现在电子元件中,节流出现在流体流动中 而JavaScript是事件驱动的,大量的操作会触发事件,加入到事件队列中处理. 而对于某些频繁的事件处理会造成性能的损耗,我们就可以通过防抖和节流来限制事件频繁的发生: 防抖和节流函数目前已经是

  • JS防抖节流函数的实现与使用场景

    目录 一.什么是函数防抖 1.为什么需要函数防抖? 2.函数防抖的要点 3.函数防抖的实现 4.函数防抖的使用场景 二.什么是函数节流 1.函数节流的要点 2.函数节流的实现 3.函数节流的使用场景 总结 一.什么是函数防抖 概念:函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间. 1.为什么需要函数防抖? 前端开发过程中,有一些事件,常见的例如,onresize,scroll,mousemove ,

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

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

  • 简单实现节流函数和防抖函数过程解析

    在日常开发中有很多场景我们都需要用到节流函数和防抖函数,比如:实现输入框的模糊查询因为需要轮询ajax,影响浏览器性能,所以需要用到节流函数:实现手机号.姓名之类的的验证,往往我们只需要验证一次,这个时候我们就需要用到防抖函数:但是网上的很多资料都是不够具体和便于理解.今天自己翻阅了一些资料之后,来简单的谈谈我对节流函数和防抖函数的理解,希望能帮助大家理解: 节流函数 顾名思义,就是节省流量节省内存性能的一种函数,可以理解为是一种性能优化方案: 举个例子:一个水龙头一直在滴水,可能一次性会滴很多

  • js防抖函数和节流函数使用场景和实现区别示例分析

    本文实例讲述了js防抖函数和节流函数使用场景和实现区别.分享给大家供大家参考,具体如下: 开发过程中,都遇到过某个事件被频发触发的场景,比如resize,scroll事件,input事件,而对应的事件处理函数也会被高频率调用,这时会增加浏览器负担,用户体验也不好,这也是防抖函数和节流函数存在的意义和使用场景. 函数防抖(debounce): 持续触发事件时,在设定时间段内没有被触发,才去调用事件处理函数,在设定时间段内如果事件又被触发,则不调用事件处理函数,并从触发事件时间重新开始延时. 具体实

  • 什么是JavaScript的防抖与节流

    目录 一.函数防抖(debounce) 1. 什么是防抖? 二.函数节流 2.1 定时器实现 2.2 时间戳实现 2.3 时间戳+定时器 一.函数防抖(debounce) 1. 什么是防抖? 函数防抖: 在频繁触发某一个事件时,一段时间内不再触发该事件后才会去调用对应的回调函数,在设定间隔时间内如果下一次事件被触发, 那么就重新开始定时器,直到事件触发结束. 规定时间内没有继续触发事件的前提下,再去调用事件处理函数: 具体如下面的例子所示: /*定义防抖函数 * func:传入一个函数,事件不再

  • JavaScript的防抖和节流一起来了解下

    目录 1.前言 2.函数防抖(debounce) 延迟防抖 前缘防抖 防抖函数实现总结 3.函数节流(throttling) 延迟节流 前缘节流 节流函数实现总结 4.两者区别 5.应用场景 总结 1. 前言 首先来举个例子.百度首页的百度输入框,用户输入的时候,每次输入的信息,我们都能看到百度服务器返回给我们的联想关键字.我们每改动一个字,它就换一次联想词,这是我们肉眼能看到的速度,实际上如果不加以处理,可能已经上服务器发起了好几十次的同一个关键字联想请求了,具体速度依赖于不同的pc等机器上的

  • JavaScript深入理解节流与防抖

    目录 一.js防抖和节流 二.为什么滚动scroll.窗口resize等事件需要优化 三.滚动和页面渲染前端性能优化的关系 四.防抖Debounce 1 防抖Debounce情景 2 防抖原理 3 防抖函数简单实现 4 防抖函数的演化过程 ①this event绑定问题 ②立即触发问题 ③返回值问题 ④取消防抖,添加cancel方法 五.节流Throttle 1 节流Throttle情景 2 节流原理 3 节流实现—时间戳和定时器 4 节流函数的演化过程 ①时间戳触发 ②定时器触发 ③结合时间戳

  • JavaScript中防抖和节流的区别及适用场景

    目录 前言 防抖 例如 代码演示 节流 例如 代码演示 前言 防抖和节流,这个在我们的前端生涯中,这两个名词肯定不陌生,甚至经常被人问起: 两者有什么区别? 分别用于什么场景? ps:这就是高频的面试题了吧! 防抖 防抖是什么呢? 形象的的说就是:防止抖动(防抖函数内心独白:“你就抖动吧!等你不抖动了,我们在进行下一步”) 例如 一个搜索输入框, 用户不停的进行输入(这个时候就是抖动的过程), 等用户输入停止之后,再触发搜索. 代码演示 function debounce(fn, delay =

  • JavaScript中防抖和节流的实战应用记录

    目录 前言 为什么我们需要防抖/节流 防抖 节流 总结 前言 你可能会遇到这种的情况,一个站点使用自动填充的文本框,内容的拖拽,效果的滚动.那么,你遇到防抖和截流的概率还是很高的.为了使得这些操作,比如自动填充能够顺畅工作,你需要引入防抖和截流功能. 防抖 -> Debounce 节流 -> Throttle 为什么我们需要防抖/节流 开篇已经简单提了,debounce/throttle 能让你的站点表现更优异.它们工作原理是通过减少动作发起的次数.我们简单举个例子,自动填充文本框触发接口请求

随机推荐