返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript中防抖和节流的实战应用记录
  • 552
分享到

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

2024-04-02 19:04:59 552人浏览 八月长安
摘要

目录前言为什么我们需要防抖/节流防抖节流总结前言 你可能会遇到这种的情况,一个站点使用自动填充的文本框,内容的拖拽,效果的滚动。那么,你遇到防抖和截流的概率还是很高的。为了使得这些操

前言

你可能会遇到这种的情况,一个站点使用自动填充的文本框,内容的拖拽,效果的滚动。那么,你遇到防抖和截流的概率还是很高的。为了使得这些操作,比如自动填充能够顺畅工作,你需要引入防抖和截流功能。

  • 防抖 -> Debounce
  • 节流 -> Throttle

为什么我们需要防抖/节流

开篇已经简单提了,debounce/throttle 能让你的站点表现更优异。它们工作原理是通过减少动作发起的次数。我们简单举个例子,自动填充文本框触发接口请求,如下:

input.addEventListener("input", e => {
  fetch(`/api/getOptions?query=${e.target.value}`)
    .then(res => res.JSON())
    .then(data => setOptions(data))
})

?上面的事件监测器,监听到输入文本框发生更改,就基于文本框的内容触发一个查询接口。这看起来还不错,但是用户输入 Samantha 文字会发生什么?

当用户输入 S,事件监测器触发请求,并带上选项 S。当此请求正在调用的时候,Sa 输入内容会再次被监听,我们将重新以 Sa 为选项内容发起新的请求。以此类推,这种请求会持续到我们输完 Samantha 的内容。

这会在短时间内发起 8 次请求,但是我们只关心最后一次请求。这意味着前 7 的接口请求都是不必要的,纯属浪费时间和金钱。

为了避免不必要的请求发生,我们就需要防抖和截流。

防抖

我们先来谈下防抖,因为它是解决自动文本框类问题的理想解决方案。防抖的原理是延迟一段时间吊起我们的函数。如果在这个时间段没有发生什么,函数正常进行,但是有内容发生变更后的一段时间触发函数。这就意味着,防抖函数只会在特定的时间之后被触发。

在我们的例子中,我们假设延迟 1 秒触发。也就是当用户停止输入内容后 1 秒,接口强求被吊起。如果我们在 1 秒内输完 Samantha 内容,请求查询内容就是 Samantha。下面我们看看怎么应用防抖。

function debounce(cb, delay = 250) {
  let timeout

  return (...args) => {
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      cb(...args)
    }, delay)
  }
}

上面的防抖函数带有 cb 回调函数参数和一个延时的参数。我们在 debound 函数后返回回调函数,这种包装的方式,保证过了 delay 秒之后,回调函数才会被调用。最后,我们在每次调用 debounce 函数时清楚现有的定时器,以确保我们在延迟完成之前调用 debouce 函数,并重新计时。

这意味着如果用户在 1 秒内,每隔 300毫秒触发一次输入,上面 debouce 函数如下方式工作。

// Type S - Start timer
// Type a - Restart timer
// Type m - Restart timer
// Type a - Restart timer
// Type n - Restart timer
// Wait 1 second
// Call debounced function with Saman
// Type t - Start timer
// No more typing
// Call debounced function with Samant

不知你注意到没有,即使我们已经输入了 Saman 文案动作超过了一秒中,回调函数也不会调起,知道再过 1 秒钟才被调用。现在,看我们怎么引用防抖函数。

const updateOptions = debounce(query => {
  fetch(`/api/getOptions?query=${query}`)
    .then(res => res.json())
    .then(data => setOptions(data))
}, 1000)

input.addEventListener("input", e => {
  updateOptions(e.target.value)
)}

我们把请求函数放到回调函数中。

防抖函数在自动填充的情形非常好用,你也可以使用在其他地方,你想将多个触发请求变成一个触发,以缓解服务器的压力。

节流

像防抖一样,节流也是限制请求的多次发送;但是,不同的是,防抖是每隔指定的时间发起请求。举个例子,如果你在 throttle 函数中设置延迟时间是 1 秒,函数被调用执行,用户输入每隔 1秒发起请求。看下下面的应用,你就明白了。

function throttle(cb, delay = 250) {
  let shouldWait = false

  return (...args) => {
    if (shouldWait) return

    cb(...args)
    shouldWait = true
    setTimeout(() => {
      shouldWait = false
    }, delay)
  }
}

debounce 和 throttle 函数都有一样的参数,但是它们主要的不同是,throttle 中的回调函数在函数执行后立马被调用,并且回调函数不在定时器函数内。回调函数要做的唯一事情就是将 shouldWait 标识设置为 false。当我们第一次调用 throttle 函数,会将 shouldWait 标识设置为 true。这延时的时间内再次调用 throttle 函数,那就什么都不做。当时间超出了延时的时间,shouldWait 标识才会设置为 false。

假设我们每隔 300 毫秒输入一个字符,然后我们的延时是 1 秒。那么 throttle 函数会像下面这样工作:

// Type S - Call throttled function with S
// Type a - Do nothing: 700ms left to wait
// Type m - Do nothing: 400ms left to wait
// Type a - Do nothing: 100ms left to wait
// Delay is over - Nothing happens
// Type n - Call throttled function with Saman
// No more typing
// Delay is over - Nothing happens

如果你留意看,你会发现第 1200 毫秒的时候,第二次 throttle 函数才会被触发。已经延迟了我们预设时间 200 毫秒。对于节流的需求来说,目前的 throttle 函数已经满足了需求。但是我们做些优化,一旦 throttle 函数中的延时结束,我们就调用函数的前一个迭代。我们像下面这样子应用。

function throttle(cb, delay = 1000) {
  let shouldWait = false
  let waitingArgs
  const timeoutFunc = () => {
    if (waitingArgs == null) {
      shouldWait = false
    } else {
      cb(...waitingArgs)
      waitingArgs = null
      setTimeout(timeoutFunc, delay)
    }
  }

  return (...args) => {
    if (shouldWait) {
      waitingArgs = args
      return
    }

    cb(...args)
    shouldWait = true
    setTimeout(timeoutFunc, delay)
  }
}

上面的代码有点吓人,但是原理都一样。不同的是,在 throttle 函数延时时,后者存储了前一个 args 参数值作为变量 waitingArgs。当延迟完成后,我们会检查 waitingArgs 是否有内容。如果没有内容,我们会将 shouldWait 设置为 false,然后进入下一次触发。如果 waitingArgs 有内容,这就意味着延时到了之后,我们将会带上 waitingArgs 参数触发我们的回调函数,然后重置我们的定时器。

这个版本的 throttle 函数也是延时时间为 1 秒,每隔 300 毫秒输入值,效果如下:

// Type S - Call throttled function with S
// Type a - Save Sa to waiting args: 700ms left to wait
// Type m - Save Sam to waiting args: 400ms left to wait
// Type a - Save Sama to waiting args: 100ms left to wait
// Delay is over - Call throttled function with Sama
// Type n - Save Saman to waiting args: 700ms left to wait
// No more typing
// Delay is over - Call throttled function with Saman

正如你所看到的,每次我们触发 throttle 函数时,如果延时时间结束,我们要么调用回调函数,要么保存要在延时结束时使用的参数。如果这个参数有值的话,当延时结束时,我们将使用它。这就保证了 throttle 函数在延时结束时获取到最新的参数值。

我们看下怎么应用到我们的例子中。

const updateOptions = throttle(query => {
  fetch(`/api/getOptions?query=${query}`)
    .then(res => res.json())
    .then(data => setOptions(data))
}, 500)

input.addEventListener("input", e => {
  updateOptions(e.target.value)
)}

你会发现,我们的应用跟 debounce 函数很相似,除了将 debounce 名改为 throttle。

当然,自动填充文本内容例子,对 throttle 函数并不适用,但是,如果你处理类如更改元素大小,元素拖拉拽,或者其他多次发生的事件,那么 throttle 函数是理想的选择。因为 throttle 每次延时结束时,你都会获得有关事件的更新信息,而 debounce 需要等待输入后延时后才能触发。总的来说,当你想定期将多个事件组合成一个事件时, throttle 是理想的选择。

本文为译文,采用意译

嗯~

我们来总结下,读完了上面的内容,可以简单这么理解:

  • 防抖:你可以无限限次触发,但是在指定的 Delay 时间内监听到你没有新的触发事件了,就该我主角上场了。
  • 节流:不管你触发多少次,在指定的 Delay 时间到了以后,我必须上场一次

总结

到此这篇关于javascript中防抖和节流的文章就介绍到这了,更多相关JavaScript防抖和节流应用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: JavaScript中防抖和节流的实战应用记录

本文链接: https://lsjlt.com/news/147582.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JavaScript中防抖和节流的实战应用记录
    目录前言为什么我们需要防抖/节流防抖节流总结前言 你可能会遇到这种的情况,一个站点使用自动填充的文本框,内容的拖拽,效果的滚动。那么,你遇到防抖和截流的概率还是很高的。为了使得这些操...
    99+
    2024-04-02
  • JavaScript的防抖和节流案例
    目录防抖节流: 防抖:在一定的时间内只执行最后一次任务; 节流:一定的时间内只执行一次; 防抖 <button id="debounce">点我防抖!</bu...
    99+
    2024-04-02
  • JavaScript的防抖和节流怎么实现
    这篇文章主要介绍了JavaScript的防抖和节流怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript的防抖和节流怎么实现文章都会有所收获,下面我们一起来看看吧。1. 前言首先来举个例子。...
    99+
    2023-06-29
  • javascript的防抖和节流是什么
    这篇文章将为大家详细讲解有关javascript的防抖和节流是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一:为什么需要防抖与节流 防抖和节流都是为了解决短时间内大量触发某函数或者事件而导...
    99+
    2023-06-28
  • JavaScript中函数的防抖与节流怎么应用
    本文小编为大家详细介绍“JavaScript中函数的防抖与节流怎么应用”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript中函数的防抖与节流怎么应用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一...
    99+
    2023-06-29
  • 怎么理解javascript中防抖和节流
    本篇内容介绍了“怎么理解javascript中防抖和节流”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • Javascript的防抖和节流方法怎么用
    本篇内容主要讲解“Javascript的防抖和节流方法怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Javascript的防抖和节流方法怎么用”吧!1. 什么是防抖【解释】: 防...
    99+
    2023-06-29
  • 老生常谈Javascript的防抖和节流
    目录1. 什么是防抖2、什么是节流3、节流阀总结1. 什么是防抖 【解释】: 防抖策略(debounce)是当事件被触发后,延迟 n 秒后再执行回调,如果在这 n 秒内事件...
    99+
    2024-04-02
  • javascript的防抖和节流你了解吗
    一:为什么需要防抖与节流  防抖和节流都是为了解决短时间内大量触发某函数或者事件而导致的性能问题,比如在 1.用户体验上,触发频率过高导致的响应速度跟不上触发频率,出现延迟...
    99+
    2024-04-02
  • JavaScript中节流和防抖的区别是什么
    这期内容当中小编将会给大家带来有关JavaScript中节流和防抖的区别是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。节流概念(Throttle)按照设定的时间固定...
    99+
    2024-04-02
  • JavaScript中防抖和节流的区别及适用场景
    目录前言防抖例如代码演示节流例如代码演示前言 防抖和节流,这个在我们的前端生涯中,这两个名词肯定不陌生,甚至经常被人问起: 两者有什么区别?分别用于什么场景? ps:这就是高频的面试...
    99+
    2024-04-02
  • JS中节流和防抖怎么实现
    本篇内容主要讲解“JS中节流和防抖怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JS中节流和防抖怎么实现”吧!引言在前端开发中,经常和DOM、BOM打交道,例如:窗口的resize、sc...
    99+
    2023-07-02
  • 详解Java中的防抖和节流
    目录概念防抖(debounce)节流(throttle)区别Java实现防抖(debounce)防抖测试1防抖测试2防抖测试简易版节流(throttle)节流测试1彩蛋解决方法1解决...
    99+
    2022-11-13
    Java防抖 Java 节流 Java 防抖 节流
  • uniapp项目使用防抖及节流的方案实战
    目录此方案出现的理由实现方案及效果总结此方案出现的理由 小程序中无法使用vue.directive的指令方法函数实现防抖节流传统的防抖节流方式相对繁琐 实现方案及效果 新建一个deb...
    99+
    2023-01-28
    uniapp 防抖 uniapp 节流防抖
  • vue中防抖和节流的使用方法
    目录前言概念防抖定义使用场景代码在vue中使用节流定义使用场景代码在vue中使用总结前言 在一个电影项目中,我想在电影的列表中,保存下拉的当前位置,防止你切换页面后,再切换回当前的电...
    99+
    2024-04-02
  • JavaScript中函数的防抖与节流详解
    目录一、函数的节流1.1 定义1.2 解决方法1.3 案例演示1.3 .1  代码演示1.3 .2  运行结果1.3 .3  添加函数节流操作1.3 ....
    99+
    2024-04-02
  • vue中如何使用防抖和节流
    本篇文章给大家分享的是有关vue中如何使用防抖和节流,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。概念说白了, 防抖节流就是使用定时器 来实现我们的目的。防抖(debounce...
    99+
    2023-06-20
  • JS节流和防抖的区分和实现
    本篇内容主要讲解“JS节流和防抖的区分和实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JS节流和防抖的区分和实现”吧!节流概念(Throttle)按照设定的...
    99+
    2024-04-02
  • JavaScript的防抖和节流一起来了解下
    目录1. 前言2. 函数防抖(debounce)延迟防抖前缘防抖防抖函数实现总结3. 函数节流(throttling)延迟节流前缘节流节流函数实现总结4. 两者区别5. 应用场景总结...
    99+
    2024-04-02
  • javascript函数的节流和防抖是什么意思
    本篇内容介绍了“javascript函数的节流和防抖是什么意思”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作