当前位置: 代码迷 >> 综合 >> underscore.js中节流函数的解析
  详细解决方案

underscore.js中节流函数的解析

热度:61   发布时间:2023-09-20 16:00:33.0

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