src/misc/debounce.js
function debounce(func, wait, invokeApply, $timeout) {
  /**
   * @type {?angular.IPromise}
   */
  let timeout = null;
  return /** @type {T} */(
    /**
     * @this {any} The context
     */
    function(...args) {
      const context = this;
      const later = function() {
        timeout = null;
        func.apply(context, args);
      };
      if (timeout !== null) {
        $timeout.cancel(timeout);
      }
      timeout = $timeout(later, wait, invokeApply);
    }
  );
}
function debounce(func, wait, invokeApply, $timeout) {
  /**
   * @type {?angular.IPromise}
   */
  let timeout = null;
  return /** @type {T} */(
    /**
     * @this {any} The context
     */
    function(...args) {
      const context = this;
      const later = function() {
        timeout = null;
        func.apply(context, args);
      };
      if (timeout !== null) {
        $timeout.cancel(timeout);
      }
      timeout = $timeout(later, wait, invokeApply);
    }
  );
}
function debounce ( func , wait , invokeApply , $timeout ) { /**
   * @type {?angular.IPromise}
   */ let timeout = null ; return /** @type {T} */ ( /**
     * @this {any} The context
     */ function ( ... args ) { const context = this ; const later = function ( ) { timeout = null ; func . apply ( context , args ) ; } ; if ( timeout !== null ) { $timeout . cancel ( timeout ) ; } timeout = $timeout ( later , wait , invokeApply ) ; } ) ; }
Provides a debounce function used to debounce calls to a user-provided function.
@template {function(?): void} T args
@typedef {function(T, number, boolean): T} miscDebounce
 
@template {function(?): void} T args
@param {T} func The function to debounce.
@param {number} wait The wait time in ms.
@param {boolean} invokeApply Whether the call to `func` is wrapped into an `$apply` call.
@param {angular.ITimeoutService} $timeout Angular timeout service.
@return {T} The wrapper function.
@private
@hidden
Provides a debounce function used to debounce calls to a user - provided function .