JavaScript 防抖和节流
本文将介绍防抖和节流,两种在前端中节省资源的方法。
一、为什么需要防抖和节流?
在前端开发中,我们往往需要监听某个事件并做相应的 “处理”。但在实际的开发中,我们不需要始终对某个事件做处理,这是一件无用且浪费资源的事情。
此时,我们便可以使用防抖和节流,在尽量不影响监听的情况下,减少 “处理” 所耗费的资源。
假设这样一个场景,我们需要监听鼠标的移动,并将坐标显示在屏幕之中,如下:
显而易见的是,监听鼠标的移动全程无意义的。我们只需要获取鼠标最终到达的目标,或者每隔一段时间获取一次鼠标的坐标即可。
我们可以像上面那样,对鼠标的每次移动都做响应,因为我们现在的 “处理” 是不太耗费性能的。但如果我们需要监听坐标并发送网络请求呢?如果我们需要监听坐标并做复杂运算呢?在这种情况下,我们就会因为无用的 “处理” 而影响 Web 应用与服务器的运行。
二、防抖
1. 什么是防抖?
触发后等待 n 秒再执行方法,重复触发则重新计时。
2. 实现方法
(1) 等待 n 秒再执行
fun.apply(obj, ...参数)
的作用是:以obj
为 this,以...参数
为参数,调用fun()
方法arguments:即方法的所有参数
在这里,它代表的是:调用 return 回去的方法时传入的参数
fun.apply(this, arguments)
的作用是,使得无论在什么地方调用了fun()
,fun()
的 this 都会指向调用者,且所有参数都会传入
1 |
|
(2) 重复触发则重新计时
- 通过
timeout
变量进行计时并调用- 以闭包的方式,防止外界污染计时器
1 |
|
(3) 返回参数
- 上面的做法并不支持获取返回值,如果需要获取返回值,可以在
debounce()
方法中获取执行结果并返回- 由于方法并不是同步执行(需要等待计时完成后再执行),因此可以使用 Promise 异步返回结果
1 |
|
3. 用法
调用
debounce()
方法获取 “经防抖处理后的方法”1
let debounceFun = debounce(fun, 时长)
在事件的处理处,用 “经防抖处理后的方法” 替代
1
2
3element.addEventListener('事件', function (e) {
debounceFun(e.target.value)
})
如何保证一个方法一个计时器:
按用法要求,一个方法只应调用一次
debounce()
。因此,计时器被创建,”经防抖处理后的方法” 被创建并返回。此后再调用 “经防抖处理后的方法”,都会清空计时器,并计时准备执行。
三、节流
1. 什么是节流?
让函数在一段时间内只执行一次,有节制地执行。
2. 实现方法
1 |
|
3. 用法
调用
throttle()
方法获取 “经节流处理后的方法”1
let throttleFun = throttle(fun, 时长)
在事件的处理处,用 “经节流处理后的方法” 替代
1
2
3element.addEventListener('事件', function (e) {
throttleFun(e.target.value)
})