什么是防抖和节流?有什么区别?如何实现?

2021-02-02 17:41发布

7条回答
刘家起 - coding
2楼 · 2021-02-02 19:24

函数防抖:将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:使得一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行。

区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。


一个Ai
3楼 · 2021-02-03 08:54

防抖节流的作用都是防止函数多次调用。区别在于,假设一个用户一直触发这个函数,且每次触发函数的间隔小于wait,防抖的情况下只会调用一次,而节流的 情况会每隔一定时间(参数wait)调用函数。

我是大脸猫
4楼 · 2021-02-03 09:37

一、防抖

场景:在滚动事件中需要做个复杂计算或者实现一个按钮的防二次点击操作。这些需求都可以通过函数防抖动来实现。尤其是第一个需求,如果在频繁的事件回调中做复杂计算,很有可能导致页面卡顿,不如将多次计算合并为一次计算,只在一个精确点做操作。
一般的防抖会有immediate选项,表示是否立即调用。

// 这个是用来获取当前时间戳的function now() {
  return +new Date()}/**
 * 防抖函数,返回函数连续调用时,空闲时间必须大于或等于 wait,func 才会执行
 *
 * @param  {function} func        回调函数
 * @param  {number}   wait        表示时间窗口的间隔
 * @param  {boolean}  immediate   设置为ture时,是否立即调用函数
 * @return {function}             返回客户调用函数
 */function debounce (func, wait = 50, immediate = true) {
  let timer, context, args  // 延迟执行函数
  const later = () => setTimeout(() => {
    // 延迟函数执行完毕,清空缓存的定时器序号
    timer = null
    // 延迟执行的情况下,函数会在延迟函数中执行
    // 使用到之前缓存的参数和上下文
    if (!immediate) {
      func.apply(context, args)
      context = args = null
    }
  }, wait)

  // 这里返回的函数是每次实际调用的函数
  return function(...params) {
    // 如果没有创建延迟执行函数(later),就创建一个
    if (!timer) {
      timer = later()
      // 如果是立即执行,调用函数
      // 否则缓存参数和调用上下文
      if (immediate) {
        func.apply(this, params)
      } else {
        context = this
        args = params      }
    // 如果已有延迟执行函数(later),调用的时候清除原来的并重新设定一个
    // 这样做延迟函数会重新计时
    } else {
      clearTimeout(timer)
      timer = later()
    }
  }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

整体函数实现的不难,总结一下。

1.对于按钮防点击来说的实现:如果函数是立即执行的,就立即调用,如果函数是延迟执行的,就缓存上下文和参数,放到延迟函数中去执行。一旦我开始一个定时器,只要我定时器还在,你每次点击我都重新计时。一旦你点累了,定时器时间到,定时器重置为 null,就可以再次点击了。

2.对于延时执行函数来说的实现:清除定时器ID,如果是延迟调用就调用函数

二、节流

防抖动和节流本质是不一样的。防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。

高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率。

思路:每次触发事件时都判断当前是否有等待执行的延时函数。

function throttle(fn) {
     let canRun = true; // 通过闭包保存一个标记
     return function () {
       if (!canRun) return; // 在函数开头判断标记是否为 true,不为 true 则 return
       canRun = false; // 立即设置为 false
       setTimeout(() => { // 将外部传入的函数的执行放在 setTimeout 中
         fn.apply(this, arguments);
         // 最后在 setTimeout 执行完毕后再把标记设置为 true(关键) 
         //表示可以执行下一次循环了。当定时器没有执行的时候
         //标记永远是 false,在开头被 return 掉
         canRun = true;
       }, 500);
     };
   }
   function sayHi(e) {
     console.log(e.target.innerWidth, e.target.innerHeight);
   }
   window.addEventListener('resize', throttle(sayHi));



寂静的枫林
5楼 · 2021-02-03 17:07

函数防抖:将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:使得一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行。

区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。


一朵大红花啊
6楼 · 2021-02-04 17:14

防抖

触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间

节流

高频触发某个事件,在n秒内只会执行一次


桃酥超好吃
7楼 · 2021-02-04 19:30

1、函数防抖

函数防抖就是我们在一段时间内频繁触发同一个事件,可能会十分的影响性能。想要在一段时间内只触发一次。这就要用到防抖和节流。举个例子,防抖是频繁触发后,1s内没有再触发时才调用事件处理程序。

function debounce(callback, time) {

        var timer;

        //使用闭包,可以避免污染全局变量

        return function () {

            clearTimeout(timer) //清除计时器

            //重新开始计时

            var args = arguments

            timer = setTimeout(() => {

                callback.apply(null, args)

            }, time);

        }

    }

    //测试案例

    var handle = debounce(function (a, b) {

        console.log(a, b)

    }, 1000)

    [removed] = function () {

        handle(12)

    }


2、函数节流

和防抖相对应的就是节流了,节流就是在一段时间内只触发一次!

function throttle(callback, time, immediately) {

        if (immediately) {//是否立即执行一次

            var t;

            return function () {

                //之前没有计时 或 距离上次执行的时间已超过规定的值

                if (!t || Date.now() - t >= time) {

                    callback.apply(nullarguments)

                    //得到的当前时间戳

                    t = Date.now()

                }

            }

        } else {//如果不立即执行一次,那么这个时间让他延迟多长时间后再执行

            var timer;

            return function () {

                if (timer) return

                var args = arguments

                timer = setTimeout(() => {

                    callback.apply(null, args)

                    timer = null

                }, time);

            }

        }

    }



征戰撩四汸
8楼 · 2022-06-10 17:21

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

  节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

  函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。


1、防抖(类似于 电梯 屏保 类的)

在固定时间内没有触发事件会在固定时间结束后触发,如果在固定时间内触发了就会延长固定时间

防抖主要利用定时器实现

//用定时器实现防抖

function debounce(func,wait) {

    var timer=null;

    return function() {

    //保存当前调用的dom对象

     var _this=this;

     //保存事件对象

     var args=arguments;

     clearTimeout(timer)

     timer=setTimeout(function() {

         func.apply(_this,args)

     },wait)

    }

2、节流

无论在固定时间内是否有事件触发,都会按照固定时间规律触发

时间戳

定时器

相关问题推荐

  • 回答 120

    相对前几年来说,要高上不少了,毕竟入行的人也是越来越多了,基础的工作对应想要参与的人群基数越来越大,但是对于高端人才的需求还是很多,人才还是相对稀缺性的。所以,想要学web或者其他技术也一样,别等,别观望。web前端就业方向特别多包括web前端开发...

  • 回答 25

    相对定位和绝对定位是定位的两种表现形式,区别如下:一、主体不同1、相对定位:是设置为相对定位的元素框会偏移某个距离。2、绝对定位:absolute 脱离文档流,通过 top,bottom,left,right 定位。二、特点不同1、相对定位:在使用相对定位时,无论是否进行移...

  • 抓包是什么意思?2020-04-01 17:36
    回答 7
    已采纳

    抓包(packet capture)就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,也用来检查网络安全。抓包也经常被用来进行数据截取等。抓包可以通过抓包工具来查看网络数据包内容。通过对抓获的数据包进行分析,可以得到有用的信息。目前流行的...

  • 回答 89

    常用的前端框架有Bootstrap框架、React框架、Vue框架、Angular框架、Foundation框架等等

  • 回答 65
    已采纳

    前端是目的就业前景非常不错的一个计算机技术,但是自学的话还是有一定难度的,网络上自学是碎片化的,同时互联网技术跟新换代快,自己的话比较吃力也学习不到最新的技术。

  • SSR 是什么意思?2020-03-20 18:56
    回答 6

    SSR就是一台服务器,可以利用 SSR 在远程的服务器上配置 SSR,使其能够成为 SSR 节点,这样本地电脑或者其它设备利用 SSR 节点实现 VPN 或者远程上网及游戏加速等方面。ShadowsocksR(简称 SSR)是 Shadowsocks 分支,在 Shadowsocks 的基础上增加了一些数据...

  • 回答 52
    已采纳

    计算机培训方向比较多,建议找适合自己的方向选择培训编程类:JAVA、WEB、Python、C/C++、C#等测试类:软件测试运维类:云计算、网络安全设计类:UI设计、3D建模等

  • 回答 11

    1、代码判断xAxis: {type: 'time',splitLine: {show: false},interval: 3600, // 设置x轴时间间隔axisLabel: {formatter: function(value, index) {return liangTools.unix2hm(value)}}},首先要把xAxis 显示类型设置成time,然后设置对应X轴......

  • 回答 8

    HTML5 + CSS + JavaScript 开发 跨平台重用代码 

  • 回答 4

    采用rem单位自动响应,并提供独有栅格化系统快速定义宽高、边距节省css代码量,同时总结各大型移动端网页,提供一套ui颜色搭配规范,尺寸规范,字体规范等。

  • 回答 10

    iView UI、ioni、SUI

  • 回答 6

     jQTouch 

  • 回答 4

    如果只是普通的移动端用vue react 或者dva 如果是要编译成小程序什么的或者混生 就用uni-app(对应vue语法)taro(对应react) 或者纯原生 这个没有限制的,自己怎么舒服怎么来

  • 回答 4

    因为可以运用在网页和小程序的开饭中,而且开源,用着便宜,企业都很喜欢

  • 回答 10

    一、Visual Studio Code下载地址:https://code.visualstudio.com/微软在2015年4月30日Build 开发者大会上正式宣布了 Visual Studio Code 项目:一个运行于 Mac OS X、Windows和 Linux 之上的,针对于编写现代 Web 和云应用的跨平台源代码编辑器。Visual Stud...

  • 回答 9

    jQuery自带淡入淡出效果 https://www.w3school.com.cn/jquery/jquery_fade.asp 看看这个 

没有解决我的问题,去提问