zoukankan      html  css  js  c++  java
  • 防抖和节流

    防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 在给DOM绑定事件时,有些事件我们是无法控制触发频率的。 如鼠标移动事件onmousemove, 滚动滚动条事件onscroll,窗口大小改变事件onresize,瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂,就会导致响应跟不上触发,出现页面卡顿,假死现象。 在实时检查输入时,如果我们绑定onkeyup事件发请求去服务端检查,用户输入过程中,事件的触发频率也会很高,会导致大量的请求发出,响应速度会大大跟不上触发。

    针对此类快速连续触发和不可控的高频触发问题,debounce 和 throttling 给出了两种解决策略;

    debounce,去抖动。策略是当事件被触发时,设定一个周期延迟执行动作,若期间又被触发,则重新设定周期,直到周期结束,执行动作。 这是debounce的基本思想,在后期又扩展了前缘debounce,即执行动作在前,然后设定周期,周期内有事件被触发,不执行动作,且周期重新设定。

    延迟debounce,示意图:

    前缘debounce, 示意图

    debounce的特点是当事件快速连续不断触发时,动作只会执行一次。 延迟debounce,是在周期结束时执行,前缘debounce,是在周期开始时执行。但当触发有间断,且间断大于我们设定的时间间隔时,动作就会有多次执行。

    debounce 的实现

    周期内有新事件触发时,重置定时器开始时间撮,定时器执行时,判断开始时间撮,若开始时间撮被推后,重新设定延时定时器,是否立即执行选项

    // 增加前缘触发功能
    var debounce = (fn, wait, immediate=false) => {
    let timer, startTimeStamp=0;
    let context, args;

    let run = (timerInterval)=>{
    timer= setTimeout(()=>{
    let now = (new Date()).getTime();
    let interval=now-startTimeStamp
    if(interval<timerInterval){ // the timer start time has been reset,so the interval is less than timerInterval
    console.log('debounce reset',timerInterval-interval);
    startTimeStamp=now;
    run(timerInterval-interval); // reset timer for left time
    }else{
    if(!immediate){
    fn.apply(context,args);
    }
    clearTimeout(timer);
    timer=null;
    }

    },timerInterval);
    }

    return function(){
    context=this;
    args=arguments;
    let now = (new Date()).getTime();
    startTimeStamp=now; // set timer start time

    if(!timer){
    console.log('debounce set',wait);
    if(immediate) {
    fn.apply(context,args);
    }
    run(wait); // last timer alreay executed, set a new timer
    }

    }

    }

    throttling,节流的策略是,固定周期内,只执行一次动作,若有新事件触发,不执行。周期结束后,又有事件触发,开始新的周期。 节流策略也分前缘和延迟两种。与debounce类似,延迟是指 周期结束后执行动作,前缘是指执行动作后再开始周期。

    延迟throttling示意图:

    前缘throttling 示意图:

    简单版: 定时器期间,只执行最后一次操作
    var throttling = (fn, wait) => {
    let timer;
    let context, args;

    let run = () => {
    timer=setTimeout(()=>{
    fn.apply(context,args);
    clearTimeout(timer);
    timer=null;
    },wait);
    }

    return function () {
    context=this;
    args=arguments;
    if(!timer){
    console.log("throttle, set");
    run();
    }else{
    console.log("throttle, ignore");
    }
    }

    }

    原文:https://blog.csdn.net/hupian1989/article/details/80920324

  • 相关阅读:
    大数据知识简单总结
    机器学习pipeline总结
    spark SQL、RDD、Dataframe总结
    hbase介绍
    git命令教程
    hive查询语句入门(hive DDL)
    hive安装部署
    调用高德地图,通过获取的区域名称得到行政区域详情
    搭建SSM框架的配置文件
    jquery实现get的异步请求
  • 原文地址:https://www.cnblogs.com/caozhuzi/p/11175735.html
Copyright © 2011-2022 走看看