javascript 函数节流

本文介绍了一种实用的JavaScript节流实现方法,通过一个通用的函数装饰器,可以轻松地将频繁触发的事件处理函数转化为节流版本,有效降低资源消耗并提高用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.函数节流的概念,意义就不多说了,看腾讯web前端AlloyTeam团队的文章,清晰易懂。给个地址:

http://www.alloyteam.com/2012/11/javascript-throttle/

2.文章中给出3个节流的例子,但是实际项目中需要升级到节流版本的javascript函数太多了,总不能一个个对葫芦画瓢,每个函数依次修改吧。习惯Python装饰器了,决定写一个通用的javascript函数,能够将其他函数简单的包装之后,使其他函数变为节流版本。

上代码:

var throttle = function(targetFunc, delay, mustRunDelay) {
    var throttleInstance = {
        timer: null,
        lastTime: 0,
        context: null,
        args: null,

        delay: function(context, args) {
    		clearTimeout(this.timer);
    		
            var currentTime = +new Date();
            if(!this.lastTime) {
                this.lastTime = currentTime;
            }
            this.context = context;
            this.args = args;
            
            if(currentTime - this.lastTime >= mustRunDelay) {
                this.doAction();
            } else {
                this.timer = setTimeout(this.timerHandler, delay);
            }
        },
        
        doAction: function() {
            targetFunc.apply(this.context, this.args);
            this.lastTime = 0;
        },
        timerHandler: function() {
            throttleInstance.doAction();
        }
    };
    return function() {
        throttleInstance.delay(this, arguments);
    };
};

使用举例:

1. 包装单独的裸函数

比如需要监听浏览器窗口大小变化事件,每次变化输出一个字符串。

window.onresize = throttle(function(){
		console.log("resized...");
	}, 
	500, 3000
);

2. 包装全局变量的共有方法

var listener = new Object();
listener.mouseover = function(e){
    console.log("mouseover");
}
listener.click = function(e){
    console.log("click");
}
有如上 listener全局变量,以及其click和mouseover两个公有方法,两个方法都是即时响应

document.getElementById('test').onclick = throttle(listener.click, 500, 3000);
//或者
document.getElementById('test').onmouseover = function() {
	return throttle(listener.mouseover, 500, 3000);
}();//括号不能掉

经过如上包装后,即为节流版本


3.在prototype构造的对象内部包装其公有方法

var Typeahead = function (element, options) {
	//do something init...
}
Typeahead.prototype = {
    constructor: Typeahead, 
	keyup: function () {
		console.log("keyup");
	}//keyup为同步响应
}

此时keyup事件即时响应。如下改变后变为节流版本

Typeahead.prototype = {
    constructor: Typeahead, 
	doKeyUp: function () {
		console.log("keyup");
	},
	keyup: throttle(function(e){
            this.realDoKeyUp(e)
        }, 500, 3000)
    //务必用一层匿名函数嵌套this.realDoKeyUp, 因为在throttle层面访问不到this
}


4.在非prototype方式构造的对象内部包装其公有方法

var HighChartDrawer = {
	createNew: function (containerId, conf) {
		var drawer = {};
		drawer.init = function() {
			//do something init...
		};
		drawer.listenSelectChange = function () {
			console.log("change...");
	    }//listenSelectChange同步响应


            return drawer;
        }
 }
此时drawer对象的listenSelectChange是即时响应的,如下改变后成为节流版本

var HighChartDrawer = {
	createNew: function() {
		var drawer = {};
		drawer.init = function() {
				//do something init...
		};

		drawer.DoSelectChange = function() {
			console.log("change...");
		},
		drawer.listenSelectChange = throttle(function () {
			drawer.DoSelectChange(); //转一次手,转而调用真正响应函数 DoSelectChange
		}, 500, 3000)


		return drawer;
 	}
}
或者

var HighChartDrawer = {
	createNew: function(containerId, conf) {
		var drawer = {};
		drawer.init = function() {
			//do something init...
		};

		drawer.DoSelectChange = function() {
			console.log("change...");
		},
		drawer.listenSelectChange = throttle(drawer.DoSelectChange, 500, 3000)

		return drawer;
 	}
}



### 回答1: JavaScript 函数节流是一种常用的优化技术,它可以限制函数的调用频率。通常情况下,如果我们在 JavaScript 中绑定一个事件处理函数,比如绑定一个滚动事件,当用户滚动页面时,这个事件处理函数会被频繁地调用。但是,有时候我们并不希望函数被这么频繁地调用,因为这会导致性能问题,甚至可能导致浏览器崩溃。这时候,我们就可以使用函数节流来优化这个函数函数节流的基本原理是,在一段时间内(通常是一个固定的时间间隔)只允许函数被调用一次。如果在这段时间内再次调用这个函数,则会忽略后续的调用,直到这段时间结束。这样,就可以保证函数不会被频繁地调用,从而提升性能。 下面是一个简单的函数节流的例子: ``` function throttle(func, delay) { let timer = null; return function() { if (!timer) { timer = setTimeout(() => { func.apply(this, arguments); timer = null; }, delay); } } } ``` 在这个例子中,我们定义了一个函数 `throttle`,它接受两个参数:`func` 和 `delay`。`func` 是要被节流的函 ### 回答2: JavaScript函数节流是一种优化技术,用于减少在高频率触发的场景中函数被执行的次数。函数节流的核心思想是限制函数在一定时间内的执行次数,以便提高性能和用户体验。 实现函数节流的一种常见方式是使用定时器。具体步骤如下: 1. 创建一个变量来保存定时器的标识符。初始化为null。 2. 在每次触发函数之前,先检查定时器是否存在。 3. 如果定时器存在,则说明函数正在等待执行,直接返回,不执行任何操作。 4. 如果定时器不存在,则清空之前的定时器,创建一个新的定时器。 5. 在定时器中设定一个延迟时间,当延迟时间到达后执行函数。 6. 在函数内部的逻辑执行完成后,将定时器标识符设置为null,表示函数可再次被触发。 通过设置适当的延迟时间,可以控制函数的执行频率。当函数被触发时,如果在延迟时间内再次被触发,延迟时间会被重置,函数的执行会被推迟。这样可以确保函数在一定时间内只执行一次,减少了频繁执行函数的开销。 函数节流可以应用于各种场景,例如监听浏览器滚动事件、窗口大小改变事件或者用户输入事件等。在这些场景中,由于事件的触发频率较高,如果不使用函数节流,会导致函数的执行频率过高,影响性能和用户体验。 总之,JavaScript函数节流是一种通过限制函数在一定时间内执行的次数来提高性能和用户体验的优化技术。 ### 回答3: JavaScript函数节流是一种优化技术,用于控制函数的执行频率。当函数被频繁触发时,节流技术可以将函数的执行间隔固定在指定的时间段内。 实现函数节流需要定义一个时间阈值,比如500毫秒。当一个函数被调用时,会先判断距离上次执行函数的时间是否超过了阈值。如果超过了阈值,那么立即执行函数,并更新上次执行函数的时间。如果没有超过阈值,那么等待下次执行函数的时机。 一个简单的节流函数的实现如下: ``` function throttle(func, wait) { let timer = null; return function() { if (!timer) { timer = setTimeout(() => { func.apply(this, arguments); timer = null; }, wait); } }; } ``` 这个函数接收两个参数:需要节流函数func和时间阈值wait。当调用节流函数返回的函数时,会判断是否存在一个定时器。如果不存在,则创建一个定时器,在指定的时间间隔后执行函数func,并重置定时器。如果存在定时器,则无操作。 这样就可以保证在一个时间间隔内,函数最多只会被执行一次。节流技术可以有效减少频繁调用函数带来的性能损耗,提高网页的响应速度。比如在处理滚动事件、窗口大小调整等场景下,使用函数节流可以避免过于频繁的函数调用,从而提升页面的性能和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值