debounce(func, delay) {
return function(args) {
var _this = this
var _args = args
clearTimeout(func.id)
func.id = setTimeout(function() {
func.call(_this, _args)
}, delay)
}
}
function debounce(func, wait, leading, trailing) {
var timer, lastCall = 0, flag = true
return function() {
var context = this
var args = arguments
var now = + new Date()
if (now - lastCall < wait) {
flag = false
lastCall = now
} else {
flag = true
}
if (leading && flag) {
lastCall = now
return func.apply(context, args)
}
if (trailing) {
clearTimeout(timer)
timer = setTimeout(function() {
flag = true
func.apply(context, args)
}, wait)
}
}
}
数组扁平化
数组扁平化:使用递归实现
将每一项遍历,如果某一项为数组,则让该项继续调用,这里指定了depth作为扁平化的深度,因为这个参数对数组的每一项都要起作用。
柯里化
参数够了就执行,参数不够就返回一个函数,之前的参数存起来,直到够了为止。
函数节流和函数防抖
在开发过程中会遇到频率很高的事件或者连续的事件,如果不进行性能的优化,就可能会出现页面卡顿的现象,比如:
Debounce
翻译:[计] 防反跳;
在 Javascript 中,那些 DOM 频繁触发的事件,我们想在某个时间点上去执行我们的回调,而不是每次事件每次触发,我们就执行该回调。我们希望多次触发的相同事件的触发合并为一次触发(其实还是触发了好多次,只是我们只关注那一次)。简单地说,即在某段连续时间内,在事件触发后只执行一次。
实际应用场景
监听窗口大小重绘的操作。
在用户拖拽窗口时,一直在改变窗口的大小,如果我们在 resize 事件中进行一些操作,消耗将是巨大的。而且大多数可能是无意义的执行,因为用户还处于拖拽的过程中。 可以使用 函数防抖 来优化相关的处理。
在 resize 事件中,我们添加了一个 300 ms 的延迟执行逻辑。 并且在每次事件触发时,都会重新计时,这样可以确保函数的执行肯定是在距离上次 resize 事件被触发的 300 ms 后。 两次 resize 事件间隔小于 300 ms 的都被忽略了,这样就会节省很多无意义的事件触发。
搜索联想
可以看到当你输入的时候,并不会发送 ajax 请求,当停止并且指定间隔内没有输入的时候,才会执行相应的回调函数。
表单的提交
在一些与用户的交互上,比如提交表单后,一般都会显示一个loading框来提示用户,用户提交的表单正在处理中。 但是发送表单请求后就显示loading是一件很不友好的事情,因为请求可能在几十毫秒内就会得到响应。 这样在用户看来就是页面中闪过一团黑色,所以可以在提交表单后添加一个延迟函数,在XXX秒后再显示loading框。 这样在快速响应的场景下,用户是不会看到一闪而过的loading框,当然,一定要记得在接收到数据后去clearTimeout
基本版的:
Throttle
翻译: -- n. | 节流阀
throttle就是设置固定的函数执行速率,从而降低频繁事件回调的执行次数。
无论怎么触发,均按照指定的时间间隔来执行。简单地说,就是限制函数在一定时间内调用的次数。 在代码中,可以通过限制函数的调用频率,来抑制资源的消耗。
实际应用场景
1. 需要实现一个元素拖拽的效果,可以在每次
move
事件中进行重绘 DOM,但是这样做,程序的开销是非常大的。所以这里用到函数节流的方法,来减少重绘的次数。
// 函数节流的实现方案
代码中,比较关键的部分是最后部分的if .. else ..,每次回调执行以后,需要保存执行的函数的时间戳,为了计算以后的事件触发回调时与之前执行回调函数的时间戳的间隔,从而根据间隔判断要不要执行回调。
这样做的结果是,在拖拽的过程中,可以确保在 500 ms 内,只能重绘一次 DOM。 同时监听了 mousemove,两者最终的结果是一致的,但是在拖拽的过程中,函数节流版触发的事件次数会相对减少很多,相应地资源消耗会更少。
2. 通用的函数节流实现
可视化解释
如果还是对防抖和节流不太明白,可以在下面看到 debounce 和 throttle 可视化区别
总结
debounce
强制函数在某段时间内只执行一次,throttle
强制函数以固定的速率执行。在处理一些高频率触发的 DOM 事件的时候,它们都能极大提高用户体验。参考资料