-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththrottle.js
72 lines (61 loc) · 2.31 KB
/
throttle.js
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
* @desc Throttle execution of a function. Especially useful for rate limiting execution of handlers on events like resize and scroll.
*
* @param {Number} delay delay in milliseconds
* @param {Boolean} noTrailing Optional, defaults to undefined
* @param {Function} callback A function to be executed after delay milliseconds
* @param {Boolean} debounceMode If it is debounceMode
*
* @returns {Function} closure. A callback wrapper HOC
*/
module.exports = function throttle(delay, noTrailing, callback, debounceMode) {
// Timer`s ID
// Ensure callback function execute at the proper time in throttle mode.
// Ensure the rate is regular in throttle mode.
var timeoutID
// Record the last timeStamp that callback was executed.
var lastExec = 0
// noTrailing defaults to undefined
// use throttle like this: throttle(500, callback)
if(typeof noTrailing !== 'boolean') {
debounceMode = callback
callback = noTrailing
noTrailing = undefined
}
// core closure function. HOC function.
// the wrapper function will limit the rate at which callback is executed
function wrapper() {
// init variables
var self = this
var elapsed = Number(new Date()) - lastExec
var args = arguments
// exec function that callback will be executed at last
function exec() {
// update the execution time
lastExec = Number(new Date())
callback.apply(self, args)
}
//
function clear() {
timeoutID = undefined
}
if(debounceMode && !timeoutID) {
exec()
}
// clear the timer. then we will create a new timer instead of this.
if(timeoutID) {
clearTimeout(timeoutID)
}
// throttle mode.
// the elapsed time gap has more then delay
if (debounceMode === undefined && elapsed > delay) {
exec()
} else if (noTrailing !== true) {
// create a new timer instead of old.
timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay)
}
}
// return the closure HOC
// the function will exec immediately when event has occurred
return wrapper
}