js 防抖和节流 (学习笔记)


/**
 * @desc 函数节流 (牛逼版本)
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 */
function throttle(func, wait ,type) {
    if(type===1){
        let previous = 0;
    }else if(type===2){
        let timeout;
    }
    return function() {
        let context = this;
        let args = arguments;
        if(type===1){
            let now = Date.now();

            if (now - previous > wait) {
                func.apply(context, args);
                previous = now;
            }
        }else if(type===2){
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null;
                    func.apply(context, args)
                }, wait)
            }
        }
    }
}
/**
 * @desc 函数防抖 (牛逼版本)
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param immediate true 表立即执行,false 表非立即执行 
* @param 防抖只会在事件结束后执行一次处理函数 immediate则用来判断是否直接执行处理函数(func.apply()) 或 延迟执行(setTimeout(()=>{func.apply()},args))
*/ function debounce(func,wait,immediate) { let timeout; return function () { let context = this; let args = arguments; if (timeout) clearTimeout(timeout); if (immediate) { var callNow = !timeout; timeout = setTimeout(() => { timeout = null; }, wait) if (callNow) func.apply(context, args) } else { timeout = setTimeout(function(){ func.apply(context, args) }, wait); } } }
// 节流 (简易版): 解释:节流 在事件触发后会执行N次 间隔对应的时间就会执行一次
例子:设置对应时间为1 则事件触发后每一秒执行一次处理函数
var throttle = function(func, delay) { var timer = nullvar startTime = Date.now()//获取第一次当前时间戳
return function() { var curTime = Date.now() // 获取执行时的时间戳 var remaining = delay - (curTime - startTime)// 获取时间差 并获取是否到达触发的间隔时间 var context = this; var args = arguments; clearTimeout(timer); if (remaining <= 0) {// 判断是否到达触发时间 (设置的触发间隔时间)小于(当前触发于上次间隔时间) 当remaining小于0时 触发处理函数 并重新定义第一次时间戳 func.apply(context, args); startTime = Date.now(); } else { timer = setTimeout(func, remaining)// 注册定时器 } } } function handle() { console.log(Math.random()); } window.addEventListener('scroll', throttle(handle, 1000))
// 防抖(简易版) 解释:事件触发结束后才会执行一次处理函数 触发跟触发时不会进入处理函数
function antiShake(fn, delay = 300) {    
    var timer = null
   return function () {
        if (timer !== null) {
          clearTimeout(timer)
        }
     timer = setTimeout(fn, delay)
    }
}
// 处理函数
function fun() {    
  console.log('0')
}
// 滚动事件
window.addEventListener('scroll',antiShake(fun, 1000))

例子:

防抖使用场景 监听input事件输入事件 触发请求 不能每次输入都请求 浪费资源并会造成卡顿 这个时候防抖最合适

节流使用场景 监听滚动事件 选择地址栏 滚动到对应的城市 选中对应城市的字母 不能等待事件结束再去触发处理函数 则使用节流 短时间去触发处理函数 这个时候节流最合适

原文地址:https://www.cnblogs.com/wukongz/p/13530306.html