js函数防抖和节流
2019-06-22 本文已影响0人
jshan
在前端开发过程那种,需要考虑到用户频繁点击请求对后台的恶意操作情况。本文介绍的就是防抖和节流来达到减少请求频繁调用的情况。但是只能作用于用户的页面请求。
函数防抖(debounce)、函数节流(throttle)
- debounce: 事件被触发,等待n秒后再执行回调,如果在这n秒内又被触发,则重新计数
- throttle: 规定在一个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某某被触发多次,则只有一次能生效
debounce的目的是为了让一定时间段的连续的函数调用,只让其执行一次
throttle的目的是让一个函数不要执行太频繁,减少一些过快的调用来节流,例如页面滚动操作
/* debounce */
function debounce(fn, wait) {
var timer = null;
return function () {
var context = this;
var args = arguments;
// 如果在n秒内还有定时未执行,则删除之前的定时任务
if (timer) {
clearTimeout(timer);
timer = null;
}
// 重新设定定时任务
timer = setTimeout(function () {
fn.apply(context, args);
}, wait);
}
}
var fn = function () {
console.log('debounce function doing...');
}
// 第一次在1500ms后触发,之后每1000ms触发一次
setInterval(debounce(fn, 500), 1000);
// 不会触发一条
setInterval(debounce(fn, 2000), 1000);
/* throttle */
function throttle(fn, gapTime) {
var _lastTime = null;
var timer = null;
return function () {
var _nowTime = new Date().getTime();
var context = this;
var args = arguments;
if (!_lastTime) {
_lastTime = new Date().getTime();
fn.apply(context, args);
} else if (_nowTime - _lastTime < gapTime) {
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(function () {
// 这个定时函数一直都没有执行,因为当周期时间(如10ms)小于定时时间(如1000ms)时
// 总是在不停的clearTimeout和setTimeout,所以就永远进入不到这个函数体
// 除非对最外面的周期函数使用clearTimeout,那么才会执行一次这个函数体
_lastTime = new Date().getTime();
fn.apply(context, args)
}, gapTime);
} else {
_lastTime = new Date().getTime();
fn.apply(context, args);
}
}
}
var fn = function () {
console.log('throttle function doing...');
}
test = setInterval(throttle(fn, 1000), 10)
clearTimeout(test);