summaryrefslogtreecommitdiffstats
path: root/devtools/shared/throttle.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/throttle.js')
-rw-r--r--devtools/shared/throttle.js77
1 files changed, 77 insertions, 0 deletions
diff --git a/devtools/shared/throttle.js b/devtools/shared/throttle.js
new file mode 100644
index 0000000000..6d834a1d01
--- /dev/null
+++ b/devtools/shared/throttle.js
@@ -0,0 +1,77 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/**
+ * From underscore's `_.throttle`
+ * http://underscorejs.org
+ * (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Underscore may be freely distributed under the MIT license.
+ *
+ * Returns a function, that, when invoked, will only be triggered at most once during a
+ * given window of time. The throttled function will run as much as it can, without ever
+ * going more than once per wait duration.
+ *
+ * @param {Function} func
+ * The function to throttle
+ * @param {number} wait
+ * The wait period
+ * @param {Object} scope
+ * The scope to use for func
+ * @return {Function} The throttled function
+ */
+function throttle(func, wait, scope) {
+ let args, result;
+ let timeout = null;
+ let previous = 0;
+
+ const later = function() {
+ previous = Date.now();
+ timeout = null;
+ result = func.apply(scope, args);
+ args = null;
+ };
+
+ const throttledFunction = function() {
+ const now = Date.now();
+ const remaining = wait - (now - previous);
+ args = arguments;
+ if (remaining <= 0) {
+ clearTimeout(timeout);
+ timeout = null;
+ previous = now;
+ result = func.apply(scope, args);
+ args = null;
+ } else if (!timeout) {
+ timeout = setTimeout(later, remaining);
+ }
+ return result;
+ };
+
+ function cancel() {
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ previous = 0;
+ args = undefined;
+ result = undefined;
+ }
+
+ function flush() {
+ if (!timeout) {
+ return result;
+ }
+ previous = 0;
+ return throttledFunction();
+ }
+
+ throttledFunction.cancel = cancel;
+ throttledFunction.flush = flush;
+
+ return throttledFunction;
+}
+
+exports.throttle = throttle;