防抖节流

防抖节流

一、演示卡顿现象

  • 正常:事件触发非常频繁,而且每一次的触发,回调函数都要去执行(如果时间很短,而且回调内部有计算,那么很有可能出现浏览器卡顿)

二、防抖

  • 在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。(你触发完事件 n 秒内不再触发事件,我才执行)
/**
 * 防抖 正常版本,n秒后第一次触发
 * @param {Function} func 执行防抖操作的函数
 * @param {Number} interval 时间,,n秒后触发
 */

function debounce(func,interval=100){
    let timeid=null
    return function(){
        const context = this;
        const args = arguments;
        if(timeid) clearTimeout(timeid);
        timeid=setTimeout(()=>{
            func.apply(context,args);      
        },interval);
        
    }

}
/**
 * 防抖 可设置首次是否立即执行
 * @param {Function} func 执行防抖操作的函数
 * @param {Number} interval 时间,n秒后触发
 * @param {Boolean} immediate 是否立即执行函数
 */
function debounce(func,interval=100,immediate){
    let timeid=null
    return function(){
        const context = this;
        const args = arguments;
        if(timeid) clearTimeout(timeid);
        if(immediate){
            // 如果已经执行过,不再执行
            let callNow=!timeid;
            timeid=setTimeout(()=>{
                 timeid=null;
            },interval);
            if(callNow)func.apply(context,args);      
        }else{
            timeid=setTimeout(()=>{
                func.apply(context,args);      
            },interval);
        }

    }

}

三、节流

  • 规定在给定时间内,只能触发一次函数。如果在给定时间内触发多次函数,只有一次生效。(把频繁的操作变为少量的操作,使浏览器有充分时间解析代码。)
/**
 * 节流 使用时间戳,会立即执行一次
 * @param {Function} func 执行节流操作的函数
 * @param {Number} interval 时间,n秒后触发
 */
function throttle(func,interval=100){
    let previous=0;
    return function(){
        const context = this;
        const args = arguments;
        let now=+new Date();
        if(now-previous>interval){
             func.apply(context, args);
             previous = now;
        }
    }
}
/**
 * 节流 使用定时器,不会立即执行n 秒后第一次执行
 * @param {Function} func 执行节流操作的函数
 * @param {Number} interval 时间,n秒后触发
 */

function throttle(func,interval=100){
    let timeid=null;
    return function(){
        const context = this;
        const args = arguments;
        if(timeid) return;
        timeid=setTimeout(()=>{
            timeid=null;
            func.apply(context,args); 
        },interval);
    }
}

四、应用场景

函数防抖(debounce):

  • search搜索联想,用户在不断输入值时,用防抖来节约请求资源;
  • window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

函数节流(throttle):

  • 鼠标不断点击触发,mousedown(单位时间内只触发一次)
  • 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

五、总结:

  • 函数防抖和函数节流都是防止某一时间频繁触发,但原理不一样。
  • 函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。

学习:
JavaScript专题之跟着underscore学防抖
JavaScript专题之跟着 underscore 学节流
节流、防抖及使用场景

六、lodash插件防抖和节流

[lodash官网]

import {throttle} from 'lodash'

methods: {
    //鼠标进入修改响应元素的背景颜色
    //采用键值对形式创建函数,将changeIndex定义为节流函数,该函数触发很频繁时,设置50ms才会执行一次
    changeIndex: throttle(function (index){
        this.currentIndex = index
    },50),
}
posted @ 2022-03-18 23:37  黄哈哈。  阅读(148)  评论(0编辑  收藏  举报