防抖 (Debounce) 和节流 (Throttle) 的简单实现

本文详细介绍了JavaScript中两种重要的性能优化技术——防抖(debounce)和节流(throttle)。防抖用于限制函数的执行次数,在用户停止输入后执行,适用于关键词联想等场景;节流则确保在设定的时间间隔内只执行一次,适用于如页面滚动、按钮点击等高频事件。文章通过代码示例展示了两种方法的实现,包括计时器和时间戳两种方式,并探讨了它们的应用场景和区别。
摘要由CSDN通过智能技术生成


防抖和节流 都是用来处理高频发事件的。
防抖: 高频触发只会在最后执行一次
节流: 高频触发只会间隔固定的时间执行一次

防抖 Debounce

实现思路
防抖函数就是一个延迟执行的函数,时间间隔内每次触发防抖都会重新计时。

应用场景
用户输入操作,根据用户输入的关键词获取联想词。如果不做防抖,用户每输入一个字符就会触发关键词联想查询,性能和体验都不好。
防抖可以实现在用户停止输入或间隔输入时再触发联想操作。

🔖 debounce.html

<body>
  <input id="input" oninput="handleInput(event)" />
  <div id="inputValue"></div>
</body>

🔖 debounce.js

/**
 * @description: debounce
 * @param {Function} func 需要防抖的函数
 * @param {Number} wait 防抖时间
 * @param {Boolean} immediate 是否开启立即执行
 * @return {Function} debounced function
 */
const debounceFunc = (func = () => {}, wait = 500, immediate = false) => {
  let timer = null
  return (args) => {
    // 立即执行 - 在第一次执行的时候, timer = null
    immediate && !timer && func(args);

    timer && clearTimeout(timer); //清除上次计时
    timer = setTimeout((args) => {
      func(args);
      //执行完毕之后, 将 timer 置为 null, 如果开启立即执行, 下次就会立即执行
      timer = null; 
    }, wait, args);//重新计时
  }
}

immediate

防抖函数可以提供 immediate 参数实现立即执行。
实现在 首次 或者 间隔较长的时间后的首次触发时立即执行 1

节流 Throttle

实现思路
思路其实比节流要简单:节流函数就相当于是一个间隔一段时间就执行一次的函数,只要这个时间间隔内触发了节流函数(不管触发多少次[非0]),时间点到了就执行一次。可以稀释高频事件的触发频率。

有助于理解的例子:就像是每 10 分钟一趟班车,时间到了车上有人就出发,没有人就不再出发,直到有人再重新触发计时。

🔖 throttle.html

<body>
  <button onclick='handleClick(event)'>节流</button>
</body>

1. 计时器方式实现

🔖 throttle.js

/**
 * @description: throttle
 * @param {Function} func 需要节流的函数
 * @param {Number} wait 节流时间间隔
 * @return {Function} throttled function
 */
const throttleFunc = (func = () => {}, wait = 500) => {
  let running = false
  return (args) => {
    if (running) return
    running = true;
    setTimeout(() => {
      func(args)
      running = false;
    }, wait);
  }
}

const handleClick = throttleFunc(() => {
  console.log('Trigger Click')
}, 3000);

2. 时间戳方式实现

/**
  * @description: 节流 - 时间戳实现方式
  * @param {Function} func 需要节流的函数
  * @param {Number} wait 节流时间间隔
  * @return {Function} throttle function
  */
const throttleFuncTimestamp = (func = () => {}, wait = 500) => {
  let lastStartTime = Date.now()
  return (args) => {
    let thisStartTime = Date.now()
    if (Date.now() - lastStartTime < wait) return
    lastStartTime = thisStartTime
    func(args);
  }
}

const handleClick = throttleFuncTimestamp(() => {
  console.log('Trigger Click')
}, 3000);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值