前端工具包之防抖函数

前言

咱们在开发过程当中,总会封装一些公共函数来做为咱们的工具来简化代码或者复用代码,为此,我打算整理一下我平常工做中经常使用的一些封装的工具函数,本篇文章为防抖函数的相关封装前端

系列文章

1.前端工具包之深浅拷贝git

2.前端工具包之日期格式化web

3.前端工具包之防抖函数缓存

4.前端工具包之小工具bash

5.前端工具包之log美化app

背景

咱们在平常开发中常常会遇到一个需求,好比在滚动事件中须要作个复杂计算或者实现一个按钮的防二次点击操做。ide

这些需求均可以经过函数防抖动来实现。尤为是第一个需求,若是在频繁的事件回调中作复杂计算,颇有可能致使页面卡顿,不如将屡次计算合并为一次计算,只在一个精确点作操做。函数

分析

PS:防抖和节流的做用都是防止函数屡次调用。区别在于,假设一个用户一直触发这个函数,且每次触发函数的间隔小于wait,防抖的状况下只会调用一次, 而节流的 状况会每隔必定时间(参数wait)调用函数。工具

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

袖珍版的防抖理解一下防抖的实现:

// func是用户传入须要防抖的函数
// wait是等待时间
const debounce = (func, wait = 50) => {
  // 缓存一个定时器id
  let timer = 0
  // 这里返回的函数是每次用户实际调用的防抖函数
  // 若是已经设定过定时器了就清空上一次的定时器
  // 开始一个新的定时器,延迟执行用户传入的方法
  return function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, wait)
  }
}

复制代码

不难看出若是用户调用该函数的间隔小于wait的状况下,上一次的时间还未到就被清除了,因此并不会执行函数

工具封装

/**
 * 防抖函数,返回函数连续调用时,空闲时间必须大于或等于 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()
    }
  }
}
复制代码

具体的解释注释中都已经标明了,这里就不作赘述了,至于节流函数,你们能够自行实现。


开源库

我的主页 | bin-ui | bin-admin

相关文章
相关标签/搜索