Skip to content

Instantly share code, notes, and snippets.

@bullgare
Created June 24, 2014 13:49
Show Gist options
  • Save bullgare/4ec0af4b56fb535ef724 to your computer and use it in GitHub Desktop.
Save bullgare/4ec0af4b56fb535ef724 to your computer and use it in GitHub Desktop.
Throttle and Debounce for AngularJS
/**
* Throttling callbacks with specified delay.
* inspired by @link http://benalman.com/projects/jquery-throttle-debounce-plugin/
*
* Throttle is invoking callback for the first time and after that every delay.
* Debounce IS NOT invoking callback for the first time.
*/
angular.forEach(['Throttle', 'Debounce'], function (factoryName) {
module
.factory(factoryName, ['$rootScope', function ($rootScope)
{
var allTimeouts = {};
$rootScope.$on('$routeChangeStart', function() {
for (var i in allTimeouts) {
clearTimeout(allTimeouts[i]);
}
allTimeouts = {};
});
/**
*
* @param {Number} delay in ms
* @param {Boolean} noTrailing it is to prevent execution one last time after all invokation stopped
* @param {Object} $scope
* @param {Function} callback
* @returns {Function} this function will be invoked each time
*/
return function (delay, noTrailing, $scope, callback) {
var unique = Math.round(Math.random() * 1e15),
timeoutId,
lastExec = factoryName === 'Debounce' ? (+new Date) : 0;
if (typeof noTrailing != 'boolean')
{
callback = $scope;
$scope = noTrailing;
noTrailing = undefined;
}
// this wrapper will be invoked by consumers
function wrapper()
{
var me = this,
elapsed = factoryName === 'Debounce' ? 0 : ((+new Date) - lastExec),
args = arguments;
timeoutId && clearTimer();
if (elapsed > delay) {
exec();
}
else if (! noTrailing)
{
timeoutId = setTimeout(function () {exec()}, delay - elapsed);
storeTimer();
}
// Executing given function
function exec()
{
lastExec = +new Date;
clearTimer();
callback.apply(me, args);
if (! $scope.$$phase) {
$scope.$digest();
}
}
function storeTimer()
{
allTimeouts[unique] = timeoutId;
}
function clearTimer()
{
clearTimeout(timeoutId);
allTimeouts[unique] = timeoutId;
}
}
return wrapper;
};
}]);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment