Skip to content

Commit fe238e7

Browse files
authored
Avoid allocating functions and use at most one timer per interval in throttleLeadingAndTrailing (#5476)
Co-authored-by: Noeri Huisman <mrxz@users.noreply.github.com>
1 parent 1880be1 commit fe238e7

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

src/utils/index.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,30 @@ module.exports.throttleLeadingAndTrailing = function (functionToThrottle, minimu
8989
if (optionalContext) {
9090
functionToThrottle = functionToThrottle.bind(optionalContext);
9191
}
92+
var args;
93+
var timerExpired = function () {
94+
// Reached end of interval, call function
95+
lastTime = Date.now();
96+
functionToThrottle.apply(this, args);
97+
deferTimer = undefined;
98+
};
99+
92100
return function () {
93101
var time = Date.now();
94102
var sinceLastTime = typeof lastTime === 'undefined' ? minimumInterval : time - lastTime;
95-
var args = arguments;
96-
if (typeof lastTime === 'undefined' || sinceLastTime >= minimumInterval) {
103+
if (sinceLastTime >= minimumInterval) {
104+
// Outside of minimum interval, call throttled function.
105+
// Clear any pending timer as timeout imprecisions could otherwise cause two calls
106+
// for the same interval.
97107
clearTimeout(deferTimer);
108+
deferTimer = undefined;
98109
lastTime = time;
99-
functionToThrottle.apply(null, args);
110+
functionToThrottle.apply(null, arguments);
100111
} else {
101-
clearTimeout(deferTimer);
102-
deferTimer = setTimeout(function () {
103-
lastTime = Date.now();
104-
functionToThrottle.apply(this, args);
105-
}, minimumInterval - sinceLastTime);
112+
// Inside minimum interval, create timer if needed.
113+
deferTimer = deferTimer || setTimeout(timerExpired, minimumInterval - sinceLastTime);
114+
// Update args for when timer expires.
115+
args = arguments;
106116
}
107117
};
108118
};

0 commit comments

Comments
 (0)