目录

1、防抖  debounce

before

after

2、节流 throttle

before

after

 总结

tips:


1、防抖  debounce

不断触发一个方法,在规定时间内只让最后一次有效访问,如果这期间又再次触发,则重新计时

eg:

  1. 搜索时等用户完整输入内容后再发送请求
  2. 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多
  3. 文本编辑器实时保存,当无任何更改操作一秒后进行保存

before

//template
<template>
    <span>没有防抖的input</span> <input @keyup="query"/>
</template>

//js
//一段ajax请求
function query(e) {
    console.log('rquest ' + e.target.value)
}

运行结果

 每次用户的输入都会触发query方法,请求次频高

after

//template
<template>
    <span>防抖后的input</span> <input @keyup="better_query"/>
</template>

//js
import { debounce } from '../../utils/utils'
const better_query = debounce((e) => {
   console.log('rquest ' + e.target.value)
}, 300)

//utils.js

export function  debounce(fn, delay) {
    // 定时器
    let timer = null

    // 将debounce处理结果当作函数返回
    return function () {
        // 保留调用时的this上下文
        let context = this
        // 保留调用时传入的参数
        let args = arguments

        // 每次事件被触发时,都去清除之前的旧定时器
        if(timer) {
            clearTimeout(timer)
        }
        // 设立新定时器
        timer = setTimeout(function () {
            fn.apply(context, args)
        }, delay)
    }
}

运行结果

 当用户完整输入后再请求,减少请求次数,优化性能

2、节流 throttle

单位时间内,只能触发一次(首次)

eg:

  1. 滚动scroll 事件,每隔一秒计算一次位置信息

before

//js
import { onMounted } from 'vue'

const scroll = (e) => {
  console.log( '触发了滚动事件' + e.target.documentElement.scrollTop)
}

onMounted(() => {
  document.addEventListener('scroll', scroll)
})

运行结果

after

import { onMounted } from 'vue'
import { throttle } from '../../utils/utils'

const better_scroll = throttle((e) => {
  console.log('触发了滚动事件' + e.target.documentElement.scrollTop)
} , 1000)


onMounted(() => {
  document.addEventListener('scroll', better_scroll )
})

//utils.js
/**
 * @desc 函数节流
 * @param fn 函数
 * @param time 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 */

export function throttle(fn, time = 500 ,type = 2) {
    let previous,timeout
    if(type===1){
         previous = 0
    }
    return function() {
        let context = this
        let args = arguments
        if(type===1){
            let now = Date.now()
            if (now - previous > time) {
                fn.apply(context, args);
                previous = now
            }
        }else if(type===2){
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null
                    fn.apply(context, args)
                }, time)
            }
        }
    }
}

运行结果

 总结

防抖主要是为了解决事件频繁触发的问题,且仅采取频繁触发的最后一次操作。

节流也是为了解决事件频繁触发的问题,且仅采取频繁触发的第一次操作。

tips:

lodash是一个JavaScript工具库,也提供了防抖函数。可以安装后使用debounce/throttle方法

import _ from 'lodash' 
const lodashThrottleSearchAsync = _.throttle(async function () { 
    let result = await getDebounceOrThrottle() 
    console.log('result:', result) 
}, 1000)

参考

「 在线演示 」防抖与节流 - 掘金

防抖节流及在Vue里面的应用 - 掘金

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐