Jimliu


一只刚上路的前端程序猿


函数节流与函数防抖

概念

函数防抖(debounce)

当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间

函数节流(throttle)

预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期

区别

函数防抖:如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。

函数节流 :保证如果电梯第一个人进来后,10秒后准时运送一次,这个时间从第一个人上电梯开始计时,不等待,如果没有人,则不运行

实现

函数防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function debounce(fn, wait) {
var timer = null;
return function () {
var context = this
var args = arguments
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(function () {
fn.apply(context, args)
}, wait)
}
}

函数节流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function throttle(fn, wait) {
var previous = 0
var timer = null
return function () {
var context = this
var args = arguments
if (!previous) {
previous = Date.now()
fn.apply(context, args)
} else if (previous + wait >= Date.now()) {
if (timer) {
// console.log(timer)
clearTimeout(timer)
timer = null
}
// console.log(timer)
timer = setTimeout(function () {
// console.log(timer)
previous = Date.now()
fn.apply(context, args)
}, wait)
} else {
previous = Date.now()
fn.apply(context, args)
}
}
}

应用场景

函数防抖

  • 每次 resize/scroll 触发统计事件
  • 文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)

函数节流

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

编写良好的git commit(译)

原文地址 Writing good commit messages 好的commit信息至少有三个目的: 加快代码review过程 帮助我们编写好的release 为了帮助Erlang / OTP的未来维护者(可能是你!),未来五年,找出为什么对代码进行特定更改或为什么添加了特定功能。 像这样构 …

于  git 继续阅读
更早的文章

用于在node.js中设计灵活体系结构的模式(CQRS / ES / Onion)(译)

原文地址Patterns for designing flexible architecture in node.js (CQRS/ES/Onion) 在这篇文章中,我介绍了一个使用CQRS和Event Sourcing模式的项目。 它使用洋葱式架构编写,并使用TypeScript编写。 “fle …

于  node 继续阅读