tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

throttle.js (2459B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 // setImmediate is only defined when running in the worker thread
      8 /* globals setImmediate */
      9 
     10 /**
     11 * From underscore's `_.throttle`
     12 * http://underscorejs.org
     13 * (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
     14 * Underscore may be freely distributed under the MIT license.
     15 *
     16 * Returns a function, that, when invoked, will only be triggered at most once during a
     17 * given window of time. The throttled function will run as much as it can, without ever
     18 * going more than once per wait duration.
     19 *
     20 * @param  {Function} func
     21 *         The function to throttle
     22 * @param  {number} wait
     23 *         The wait period
     24 * @param  {object} scope
     25 *         The scope to use for func
     26 * @return {Function} The throttled function
     27 */
     28 function throttle(func, wait, scope) {
     29  let args, result;
     30  let timeout = null;
     31  let previous = 0;
     32 
     33  const later = function () {
     34    previous = Date.now();
     35    timeout = null;
     36    result = func.apply(scope, args);
     37    args = null;
     38  };
     39 
     40  const throttledFunction = function () {
     41    const now = Date.now();
     42    const remaining = wait - (now - previous);
     43    args = arguments;
     44    if (remaining <= 0) {
     45      if (!isWorker) {
     46        clearTimeout(timeout);
     47      }
     48      timeout = null;
     49      previous = now;
     50      result = func.apply(scope, args);
     51      args = null;
     52    } else if (!timeout) {
     53      // On worker thread, we don't have access to privileged setTimeout/clearTimeout
     54      // API which wouldn't be frozen when the worker is paused. So rely on the privileged
     55      // setImmediate function which executes on the next event loop.
     56      if (isWorker) {
     57        setImmediate(later);
     58        timeout = true;
     59      } else {
     60        timeout = setTimeout(later, remaining);
     61      }
     62    }
     63    return result;
     64  };
     65 
     66  function cancel() {
     67    if (timeout) {
     68      if (!isWorker) {
     69        clearTimeout(timeout);
     70      }
     71      timeout = null;
     72    }
     73    previous = 0;
     74    args = undefined;
     75    result = undefined;
     76  }
     77 
     78  function flush() {
     79    if (!timeout) {
     80      return result;
     81    }
     82    previous = 0;
     83    return throttledFunction();
     84  }
     85 
     86  throttledFunction.cancel = cancel;
     87  throttledFunction.flush = flush;
     88 
     89  return throttledFunction;
     90 }
     91 
     92 exports.throttle = throttle;