X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=ang%2FcrmUtil.js;h=b6a0d013104490866993547922f3a2a4368b7ea1;hb=c3ec2f80a65ea2ab45d6a84f2765f37cedc606a8;hp=f64292762bdb1f21d01a01e6aeacd5375c599224;hpb=493320d761d52dab8db1233bd2ffe3c61aac171f;p=civicrm-core.git diff --git a/ang/crmUtil.js b/ang/crmUtil.js index f64292762b..b6a0d01310 100644 --- a/ang/crmUtil.js +++ b/ang/crmUtil.js @@ -193,6 +193,40 @@ }; }]); + // Wrap an async function in a queue, ensuring that independent async calls are issued in strict sequence. + // usage: qApi = crmQueue(crmApi); qApi(entity,action,...).then(...); qApi(entity2,action2,...).then(...); + // This is similar to promise-chaining, but allows chaining independent procs (without explicitly sharing promises). + angular.module('crmUtil').factory('crmQueue', function($q) { + // @param worker A function which generates promises + return function crmQueue(worker) { + var queue = []; + function next() { + var task = queue[0]; + worker.apply(null, task.a).then( + function onOk(data) { + queue.shift(); + task.dfr.resolve(data); + if (queue.length > 0) next(); + }, + function onErr(err) { + queue.shift(); + task.dfr.reject(err); + if (queue.length > 0) next(); + } + ); + } + function enqueue() { + var dfr = $q.defer(); + queue.push({a: arguments, dfr: dfr}); + if (queue.length === 1) { + next(); + } + return dfr.promise; + } + return enqueue; + }; + }); + // Adapter for CRM.status which supports Angular promises (instead of jQuery promises) // example: crmStatus('Saving', crmApi(...)).then(function(result){...}) angular.module('crmUtil').factory('crmStatus', function($q){