js实现 throttle 和 debounce,节流,防抖详解

2019-11-25 17:05:44

1、throttle 节流:drag改变浏览器大小,触发onresize函数,实现拖动每过1秒输出一次,不足1秒,1秒后输出一次。多用于高频操作,如抢票、抢购等,无论点击多少次,只固定间隔执行一次,以减轻压力。

原理: 设置canRun作为是否执行的标志。每次触发onresize,都判断canRun的值(true执行,false不执行)。第一次应该执行,所以设置canRun初始值为true。当第一次执行后,设置canRun为false(防止下次执行),并设置计时器,以恢复canRun的值。


var canRun = true;

window.onresize = function() {

  if (!canRun){

    return;

  }

  canRun = false;

  setTimeout(function() {

    console.log('节流了');

    canRun = true;

  }, 1000);

}

        好,原理有了,接下来我们封装一个随处可用的函数,"window"只是为了理解。可以删掉:


window.canRun = true;

window.throttle = function(callback, time) {

  if (!window.canRun) {

    return;

  }

  window.canRun = false;

  setTimeout(function() {

    callback();

    window.canRun = true;

  }, time);

}

// 这样使用:

window.onresize = function() {

  window.throttle(function() {

    console.log('防抖成功'); // 业务代码

  }, 1000);

    }

 


 


 


 

2、debounce防抖:drag改变浏览器大小,触发onresize函数,实现拖动停顿1秒输出。多用于输入框,当某一次输入后停顿满n秒才会去触发远程搜索。

        原理:timer作为定时器,每次触发onresize事件,都清一下定时器(之前未执行的drag方法就不会再执行),新的定时器在1秒后执行方法,那么如果下次drag在1秒内,这次赋值的定时器又会被清掉(搜索方法不会执行),直到下次drag相对于这次drag间隔时间大于1秒(定时器可能没那么准)再执行一次方法onresize。


var timer = false;

window.onresize = function() {

  console.log('1');

  clearTimeout(timer);

  timer = setTimeout(function() {

    console.log('防抖动');

  }, 1000);

    }

        同样,封装起来使用:


timer = false;

debounce = function(callback, time) {

  clearTimeout(timer);

  timer = setTimeout(callback, time);

}

onresize = function() {

  debounce(() => {console.log('不抖了');}, 1000);

    }

 



  • 2019-10-09 15:33:31

    nuxt,nuxtjs简单介绍以及使用

    在集成的服务器端框架之间进行选择: 选择您喜欢的 UI 框架: 选择您喜欢的测试框架: 选择你想要的 Nuxt 模式 (Universal or SPA) 添加 axios module 以轻松地将 HTTP 请求发送到您的应用程序中。 添加 EsLint 以在保存时代码规范和错误检查您的代码。 添加 Prettier 以在保存时格式化/美化您的代码。

  • 2019-10-10 00:21:35

    laravel 5.6以上日志理解及日志格式定义

    Laravel/Lumen的日志默认是基于Monolog进行了一层封装,如果要求不高,用起来还是十分容易的,本文基于laravel5.6/Lumen5.6版本进行解说。5.6版对日志系统做了升级,将日志的配置单独放以了config/logging.php 配置文件中,所以现在实用多了。

  • 2019-10-10 10:10:49

    @Scheduled注解各参数详解

    每隔5秒执行一次:*/5 * * * * ? 每隔1分钟执行一次:0 */1 * * * ? 每天23点执行一次:0 0 23 * * ? 每天凌晨1点执行一次:0 0 1 * * ? 每月1号凌晨1点执行一次:0 0 1 1 * ? 每月最后一天23点执行一次:0 0 23 L * ? 每周星期天凌晨1点实行一次:0 0 1 ? * L 在26分、29分、33分执行一次:0 26,29,33 * * * ? 每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?

  • 2019-10-10 11:07:47

    Java8 - Map更优雅的迭代方式:forEach

    用于两个参数之间进行操作的函数式接口是 BiConsumer。这个函数式接口正好用来操作 Map 的 key 和 value。JDK8强化了针对 Map 类的迭代方式,新增了一个默认方法 forEach,它接收一个 BiConsumer 函数。JDK给出的描述如下:

  • 2019-10-11 13:48:00

    关于Integer比较相等的问题

    原来两个Integer类型的数字不能用==来判断,要用equal 不过Integer类型的可以与1,2这样的纯数字来判断