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 相关文章推荐
向大师们学习Javascript(视频与PPT)
Dec 27 Javascript
Javascript学习笔记4 Eval函数
Jan 11 Javascript
JavaScript前补零操作实例
Mar 11 Javascript
JavaScript实现节点的删除与序号重建实例
Aug 05 Javascript
jquery实现触发时更新下拉列表内容的方法
Dec 02 Javascript
仅9张思维导图帮你轻松学习Javascript 就这么简单
Jun 01 Javascript
详解Web使用webpack构建前端项目
Sep 23 Javascript
angular之ng-template模板加载
Nov 09 Javascript
详解Vue CLI3 多页应用实践和源码设计
Aug 30 Javascript
详解Vue调用手机相机和相册以及上传
May 05 Javascript
微信小程序开发之获取用户手机号码(php接口解密)
May 17 Javascript
针对Vue路由history模式下Nginx后台配置操作
Oct 22 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
实现 win2003 下 mysql 数据库每天自动备份
2006/12/06 PHP
PHP中foreach循环中使用引用要注意的地方
2011/01/02 PHP
php采用curl实现伪造IP来源的方法
2014/11/21 PHP
php身份证号码检查类实例
2015/06/18 PHP
弹出模态框modal的实现方法及实例
2017/09/19 PHP
YII2.0框架行为(Behavior)深入详解
2019/07/26 PHP
打豆豆小游戏 用javascript编写的[打豆豆]小游戏
2013/01/08 Javascript
js中对象的声明方式以及数组的一些用法示例
2013/12/11 Javascript
JavaScript获取浏览器信息的方法
2015/11/20 Javascript
javascript随机抽取0-100之间不重复的10个数
2016/02/25 Javascript
IE下JS保存图片的简单实例
2016/07/15 Javascript
实例解析ES6 Proxy使用场景介绍
2018/01/08 Javascript
Vue仿今日头条实例详解
2018/02/06 Javascript
浅析前端路由简介以及vue-router实现原理
2018/06/01 Javascript
layer弹出层全屏及关闭方法
2018/08/17 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
vue单页面在微信下只能分享落地页的解决方案
2019/04/15 Javascript
p5.js实现简单货车运动动画
2019/10/23 Javascript
利用Python的Twisted框架实现webshell密码扫描器的教程
2015/04/16 Python
python3 requests中使用ip代理池随机生成ip的实例
2018/05/07 Python
对Python 窗体(tkinter)树状数据(Treeview)详解
2018/10/11 Python
python单向循环链表原理与实现方法示例
2019/12/03 Python
使用pytorch实现可视化中间层的结果
2019/12/30 Python
利用matplotlib为图片上添加触发事件进行交互
2020/04/23 Python
css3闪亮进度条效果实现思路及代码
2013/04/17 HTML / CSS
经济实惠的豪华背包和行李袋:Packs Project
2018/10/17 全球购物
Delphi笔试题
2016/11/14 面试题
合同专员岗位职责
2013/12/18 职场文书
安全生产先进个人材料
2014/02/06 职场文书
党员教师一句话承诺
2014/05/30 职场文书
2014年教育工作总结
2014/11/26 职场文书
工程服务质量承诺书
2015/04/29 职场文书
2015年电信员工工作总结
2015/05/26 职场文书
如何写观后感
2015/06/19 职场文书
学习心得体会
2019/06/20 职场文书
《王者天下》第4季首话新剧照 4月9日正式开播
2022/04/07 日漫