JavaScript函数节流和函数去抖知识点学习


Posted in Javascript onJuly 31, 2018

概念

节流 (throttle) 让一个函数不要执行的太频繁,减少执行过快的调用,叫节流

去抖 (debounce) 去抖就是对于一定时间段的连续的函数调用,只让其执行一次

throttle 应用场景

  • DOM 元素的拖拽功能实现(mousemove)
  • 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
  • 计算鼠标移动的距离(mousemove)
  • Canvas 模拟画板功能(mousemove
  • 搜索联想(keyup
  • 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次

debounce 应用场景

每次 resize/scroll 触发统计事件

文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)

函数去抖的实现

我们以scroll事件为例,探究如何是实现滚动一次窗口打印一个hello world 字符串。 如果不对其节流或者去抖:

window.onscroll = function () {
 console.log('hello world');
}

这样每滚动一次,实际上会打印多个 hello world。 函数去抖背后的思路是指,某些代码不可能在没有间断的情况下连续执行。创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。

《高程三》给出了最简洁最经典的去抖代码,如下:

function debounce(method, context) {
 clearTimeout(method.tId);
 method.tId = setTimeout(function() {
 method.call(context);
 }, 1000);
}

function print() {
 console.log('hello world');
}

window.onscroll = function() {
 debounce(print);
};

再做一些改动

function debounce(delay, action) {
 var tId;
 return function () {
  var context = this;
  var arg = arguments;
  if (tId) clearTimeout(tId);
  tId = setTimeout(function () {
   action.apply(context, arg);
  }, delay);
 }
}

window.onscroll = debounce(1000, print);

函数节流的实现

函数节流就是让连续执行的函数,变为固定时间段间断地执行。 大概有两种方式实现。

其一使用时间戳来判断是否已经到回调执行时间,记录上次执行的时间戳,然后每次触发事件时执行回调,回调中判断当前时间戳距离上次执行时间戳的时间间隔是否有*s,如果是,则执行,并更新上次执行的时间戳,如此循环。

var throttle = function(delay, action) {
 var last = 0;
 return function() {
  var curr = new Date();
  if (curr - last > delay) {
   action.apply(this, arguments);
   last = curr;
  }
 }
}

第二种方法是使用定时器,比如,当scroll事件刚触发时,打印一个hello world ,然后设置一个1000ms的定时器,此后每次触发scroll事件,触发回调,如果已经存在定时器,则回调不执行方法,知道定时器出发,handler被清除,然后重新设置定时器。

var throttle = function(delay, action) {
 var timeout;
 var later = function () {
  timeout = setTimeout(function(){
   clearTimeout(timeout);
   // 解除引用
   timeout = null;
  }, delay);
 };
 later();
 if (!timeout) {
  action.apply(this, arguments);
  later();
 }
}

更新方法:

function throttlePro(delay, action) {
 var tId;
 return function () {
  var context = this;
  var arg = arguments;
  if (tId) return;
  tId = setTimeout(function () {
   action.apply(context, arg);
   clearTimeout(tId);
   // setTimeout 返回一个整数,clearTimeout 之后,tId还是那个整数,setInterval同样如此
   tId = null;
  }, delay);
 }
}
Javascript 相关文章推荐
flash javascript之间的通讯方法小结
Dec 20 Javascript
10个实用的脚本代码工具
May 04 Javascript
JavaScript获取flash对象与网上的有所不同
Apr 21 Javascript
jQuery中extend()和fn.extend()方法详解
Jun 03 Javascript
原生javascript实现自动更新的时间日期
Feb 12 Javascript
vue插件tab选项卡使用小结
Oct 27 Javascript
Bootstrap基本模板的使用和理解1
Dec 14 Javascript
微信小程序组件 marquee实例详解
Jun 23 Javascript
vue中实现上传文件给后台实例详解
Aug 22 Javascript
js脚本中执行java后台代码方法解析
Oct 11 Javascript
vue.js实现h5机器人聊天(测试版)
Jul 16 Javascript
Vue+Vant 图片上传加显示的案例
Nov 03 Javascript
JS使用遮罩实现点击某区域以外时弹窗的弹出与关闭功能示例
Jul 31 #Javascript
微信网页授权并获取用户信息的方法
Jul 30 #Javascript
axios简单实现小程序延时loading指示
Jul 30 #Javascript
JS实现HTML页面中动态显示当前时间完整示例
Jul 30 #Javascript
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
Jul 30 #Javascript
js+html5实现手机九宫格密码解锁功能
Jul 30 #Javascript
vscode中vue-cli项目es-lint的配置方法
Jul 30 #Javascript
You might like
Yii快速入门经典教程
2015/12/28 PHP
php实现简单爬虫的开发
2016/03/28 PHP
PHP实现的简单sha1加密功能示例
2017/08/27 PHP
PHP进阶学习之反射基本概念与用法分析
2019/06/18 PHP
在js中判断checkboxlist(.net控件客户端id)是否有选中
2013/04/11 Javascript
按下Enter焦点移至下一个控件的实现js代码
2013/12/11 Javascript
js判断字符长度以及中英文数字等
2013/12/31 Javascript
JS获取单击按钮单元格所在行的信息
2014/06/17 Javascript
JQuery中使用.each()遍历元素学习笔记
2014/11/08 Javascript
js实现网页收藏功能
2015/12/17 Javascript
基于JavaScript代码实现兼容各浏览器的设为首页和加入收藏
2016/01/07 Javascript
js canvas仿支付宝芝麻信用分仪表盘
2016/11/16 Javascript
值得分享的JavaScript实现图片轮播组件
2016/11/21 Javascript
vue2.0使用Sortable.js实现的拖拽功能示例
2017/02/21 Javascript
checkbox:click事件触发span元素内容改变的方法
2017/09/11 Javascript
Three.js入门之hello world以及如何绘制线
2017/09/25 Javascript
详细分析单线程JS执行问题
2017/11/22 Javascript
Angular使用过滤器uppercase/lowercase实现字母大小写转换功能示例
2018/03/27 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
2018/05/08 Javascript
Node.js assert断言原理与用法分析
2019/01/04 Javascript
vue项目中使用vue-i18n报错的解决方法
2019/01/13 Javascript
小程序中的箭头函数的具体使用
2020/06/19 Javascript
Vue点击切换Class变化,实现Active当前样式操作
2020/07/17 Javascript
微信小程序入门之绘制时钟
2020/10/22 Javascript
使用Python写CUDA程序的方法
2017/03/27 Python
python实现将读入的多维list转为一维list的方法
2018/06/28 Python
Python并发之多进程的方法实例代码
2018/08/15 Python
python实现的生成word文档功能示例
2019/08/23 Python
python+opencv实现移动侦测(帧差法)
2020/03/20 Python
PyQt5如何将.ui文件转换为.py文件的实例代码
2020/05/26 Python
如何通过python检查文件是否被占用
2020/12/18 Python
html5 Canvas绘制线条 closePath()实例代码
2012/05/10 HTML / CSS
12个不为大家熟知的HTML5设计小技巧
2016/06/02 HTML / CSS
2015年复活节活动总结
2015/02/27 职场文书
入党培养人考察意见
2015/06/08 职场文书
MySQL InnoDB ReplicaSet(副本集)简单介绍
2021/04/24 MySQL