underscore.js中节流函数的解析
- 源码
- 简化版
- 使用方式
源码
underscore.js是一个经典的js工具库,随着语言的发展,虽然现在用的少了,但它像jquery一样,甚至影响了语言的发展,足以说明其厉害之处。许多开发人员进阶首选学习的就是它,只会写业务代码的同学们一般就被困到这里,不再前进了。
本文解析一下其中的节流函数,加深对js语言的理解。
节流和防抖的区别:
防抖函数:连续触发时,刷新上一次的定时器,在一定时间段内只响应最后一次。
节流函数:连续触发时,只会在一定时间段内触发一次,不刷新时间间隔,也就是可以多次触发。
简单点说就是比如点击一个按钮,用防抖的话,狂点一通之后,只会触发一次。
用节流的话,会慢慢触发多次。
源码如下:汉字部分为我加的注释
function throttle(func, wait, options) {
var timeout, context, args, result; //闭包变量var previous = 0; //上一次触发时间if (!options) options = {
};// 尾部调用var later = function() {
previous = options.leading === false ? 0 : now();timeout = null;result = func.apply(context, args);if (!timeout) context = args = null;};// 经过包装的节流函数var throttled = function() {
var _now = now();if (!previous && options.leading === false) previous = _now;var remaining = wait - (_now - previous);context = this;args = arguments;if (remaining <= 0 || remaining > wait) {
//间隔超出wait时间if (timeout) {
clearTimeout(timeout);timeout = null;}previous = _now;result = func.apply(context, args); //头部调用if (!timeout) context = args = null;} else if (!timeout && options.trailing !== false) {
//尾部调用timeout = setTimeout(later, remaining); //延时剩余时间调用}return result;};// 动态控制节流效果throttled.cancel = function() {
clearTimeout(timeout);previous = 0;timeout = context = args = null;};return throttled;
}
因为它有头部触发和尾部触发的配置项,以及cancel功能,所以看起来比较复杂,基本原理就是比较两次触发的时间间隔,在间隔内仅触发一次或两次(头尾)。
简化版
function throttle(func, wait) {
let result, previous; // 闭包变量function throttled() {
let now = new Date().getTime()if (!previous) {
//头一次previous = nowresult = func.apply(this, arguments)} else {
let remaining = now - previous //两次间隔时间if (remaining > wait) {
//超过wait时间previous = nowresult = func.apply(this, arguments)}}return result}return throttled
}
以上是我改写的简化版。
去掉了options配置项,只支持头部调用,也就是在时间段内的开头触发。
result和previous分别是被封装函数的执行结果和上一次执行时间戳,存到闭包变量里,作为多次调用的缓存使用。
这样看起来逻辑就清晰多了,再去看原版的节流函数就会更加容易理解,所以本文可以倒着看。。。
使用方式
function updateChart() {
console.log('updateChart')
}// 节流过的函数
var throttled = throttle(updateChart, 1000)window.onresize = throttled
例如当浏览器窗口大小重置时,需要刷新echarts来重新适配大小,如果不使用防抖或节流,频繁的重绘会造成页面十分卡顿,增加了之后,性能就会好很多。
或者用在mousemove之类的频繁触发的事件上,都会有不错的效果。
欢迎来我的b站空间逛逛
https://space.bilibili.com/395672451