防抖和节流函数是开发人员会用到的两个常用的工具函数,可以自己利用setTimeout实现,不过前人栽树,后人乘凉,既然有好的轮子,就拿来用吧!

这里分别记录一下去哪网前端架构司徒正美和ionic官方库中的实现方式

防抖

先看ionic的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* Only call a function once in the given interval.
*
* @param func {Function} the function to call
* @param wait {int} how long to wait before/after to allow function calls
* @param immediate {boolean} whether to call immediately or after the wait interval
*/
debounce: function(func, wait, immediate) {
var timeout, args, context, timestamp, result;
return function() {
context = this;
args = arguments;
timestamp = new Date();
var later = function() {
var last = (new Date()) - timestamp;
if (last < wait) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) result = func.apply(context, args);
}
};
var callNow = immediate && !timeout;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (callNow) result = func.apply(context, args);
return result;
};
}

接下来是司徒正美:

1
2
3
4
5
6
7
8
9
10
    function debounce(func, delay) {
var timeout;
return function (e) {
clearTimeout(timeout);
var context = this, args = arguments;
timeout = setTimeout(function () {
func.apply(context, args);
}, delay);
};
};

节流

ionic官方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Throttle the given fun, only allowing it to be
* called at most every `wait` ms.
*/
throttle: function(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
options || (options = {});
var later = function() {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
};
return function() {
var now = Date.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
}

司徒正美:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    function throttle(fn, threshhold) {
var timeout;
var start = new Date;
var threshhold = threshhold || 160;
return function () {

var context = this, args = arguments, curr = new Date() - 0;

clearTimeout(timeout);//总是干掉事件回调
if (curr - start >= threshhold) {
console.log("now", curr, curr - start);//注意这里相减的结果,都差不多是160左右
fn.apply(context, args); //只执行一部分方法,这些方法是在某个时间段内执行一次
start = curr;
} else {
//让方法在脱离事件后也能执行一次
timeout = setTimeout(function () {
fn.apply(context, args)
}, threshhold);
}
}
}

参考链接