X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=ang%2FcrmUtil.js;h=a8b0370ad409aa7f3936b9181bba09dbe984146f;hb=0b1991948184b8d6b4e290f8514406f7fd620c21;hp=8cb6242689a559b5027862bffdcd8c816e7147ec;hpb=ae0b9f613a9d7bd38b28cbda07cb15eb7497e6b5;p=civicrm-core.git diff --git a/ang/crmUtil.js b/ang/crmUtil.js index 8cb6242689..a8b0370ad4 100644 --- a/ang/crmUtil.js +++ b/ang/crmUtil.js @@ -1,6 +1,6 @@ /// crmUi: Sundry UI helpers (function (angular, $, _) { - angular.module('crmUtil', []); + angular.module('crmUtil', CRM.angRequires('crmUtil')); // Angular implementation of CRM.api3 // @link http://wiki.civicrm.org/confluence/display/CRMDOC/AJAX+Interface#AJAXInterface-CRM.api3 @@ -306,4 +306,44 @@ }; }); + // Run a given function. If it is already running, wait for it to finish before running again. + // If multiple requests are made before the first request finishes, all but the last will be ignored. + // This prevents overwhelming the server with redundant queries during e.g. an autocomplete search while the user types. + // Given function should return an angular promise. crmThrottle will deliver the contents when resolved. + angular.module('crmUtil').factory('crmThrottle', function($q) { + var pending = [], + executing = []; + return function(func) { + var deferred = $q.defer(); + + function checkResult(result, success) { + _.pull(executing, func); + if (_.includes(pending, func)) { + runNext(); + } else if (success) { + deferred.resolve(result); + } else { + deferred.reject(result); + } + } + + function runNext() { + executing.push(func); + _.pull(pending, func); + func().then(function(result) { + checkResult(result, true); + }, function(result) { + checkResult(result, false); + }); + } + + if (!_.includes(executing, func)) { + runNext(); + } else if (!_.includes(pending, func)) { + pending.push(func); + } + return deferred.promise; + }; + }); + })(angular, CRM.$, CRM._);