source: Dev/trunk/src/qed-client/lib/async.js @ 443

Last change on this file since 443 was 443, checked in by hendrikvanantwerpen, 12 years ago

Reorganized for Node --- the SVN gods hate us all!

Lost all historical info on moved files, because SVN is a f *.

Also we have Node now, serving both the static content and forwarding
database requests.

File size: 4.0 KB
Line 
1define([
2    'dojo/_base/array',
3    'dojo/_base/lang',
4    'dojo/when',
5    'dojo/Deferred'
6],function(array,lang,when,Deferred){
7
8    /** Execute possible async functions in sequence
9     * Execute functions in order. When a function returns a Promise,
10     * the next function is only executed when the promise resolves.
11     * If the function returns a value, the next function is executed
12     * synchronously. The return value of every function is passed as argument
13     * to the next.
14     * Returns the return value of the last function in the chain.
15     */
16    function seq(functions,ctx) {
17        var d = new Deferred();
18
19        var cancelled = false;
20        var running = null;
21        function cancel(err) {
22            if ( cancelled ) { return; }
23            cancelled = true;
24            if ( running && running.cancel && !running.isFulfilled() ) {
25                running.cancel();
26            }
27            d.reject(err);
28        }
29
30        function update(fs,arg) {
31            if ( cancelled ) { return; }
32            if ( fs.length > 0 ) {
33                try {
34                    var f = fs.shift();
35                    running = when(f.call(ctx,arg))
36                    .then(function(res){
37                        update(fs,res);
38                    },function(err){
39                        cancel(err);
40                    });
41                } catch(err) {
42                    cancel(err);
43                }
44            } else {
45                d.resolve(arg);
46            }
47        }
48
49        update(functions);
50
51        return d.promise;
52    }
53
54    /** Execute possible async functions in parallel
55     * Execute all functions in parallel, resolve only when all have resolved.
56     * NB. When a function is not async, it will fully complete before the next
57     * async function is started. If you mix async and non async functions, put
58     * the sync functions last to fully exploit the async ones.
59     * Return an array with all the return values of the functions.
60     */
61    function par(functions,ctx) {
62        var d; // later: Deferred
63       
64        var cancelled = false;
65        var running = [];
66        function cancel(err) {
67            if (cancelled) { return; }
68            cancelled = true;
69            array.forEach(running,function(running){
70                if ( running && running.cancel && !running.isFulfilled() ) {
71                    running.cancel();
72                }
73            });
74            d.reject(err);
75        }
76
77        d = new Deferred(cancel);
78
79        var results = [];
80        var left = functions.length;
81        function update(res,idx) {
82            if (cancelled) { return; }
83            results[idx] = res;
84            left -= 1; // Works because/as long as AJAX/JS is single-threaded.
85            if ( left === 0 ) {
86                d.resolve(results);
87            }
88        }
89
90        array.forEach(functions,function(f,idx){
91            if (cancelled) { return; }
92            try {
93                running.push(when(f.call(ctx)).then(function(res){
94                    update(res,idx);
95                },function(err){
96                    cancel(err);
97                }));
98            } catch (err) {
99                cancel();
100            }
101        });
102
103        return d.promise;
104    }
105
106    /** Iterate over an array with async callback
107     * Execute the callback and if it's async, wait until it's finished before
108     * executing the next one.
109     */
110    function forEach(list,callback,ctx) {
111        var fs = array.map(list,function(item,index,items){
112            return lang.hitch(ctx,callback,item,index,items);
113        });
114        return seq(fs);
115    }
116
117    /** Map a list, possible async
118     * Map every element of a list, returning a promise to the mapped list.
119     */
120    function map(list,callback,ctx) {
121        var fs = array.map(list,function(item,index,items){
122            return lang.hitch(ctx,callback,item,index,items);
123        });
124        return par(fs);
125    }
126
127    return {
128        seq: seq,
129        par: par,
130        forEach: forEach,
131        map: map
132    };
133
134});
Note: See TracBrowser for help on using the repository browser.