source: Dev/trunk/src/client/dojox/lang/async.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 4.5 KB
Line 
1dojo.provide("dojox.lang.async");
2
3(function(){
4        var d = dojo, Deferred = d.Deferred, each = d.forEach, some = d.some,
5                async = dojox.lang.async, aps = Array.prototype.slice,
6                opts = Object.prototype.toString;
7
8        async.seq = function(x){
9                // summary:
10                //              Executes functions sequentially. Waits if any of them returns Deferred.
11                var fs = opts.call(x) == "[object Array]" ? x : arguments;
12                return function(init){
13                        var x = new Deferred();
14                        each(fs, function(f){ x.addCallback(f); });
15                        x.callback(init);
16                        return x;
17                };
18        };
19
20        async.par = function(x){
21                // summary:
22                //              Executes functions in parallel. Waits for all of them to finish.
23                var fs = opts.call(x) == "[object Array]" ? x : arguments;
24                return function(init){
25                        var results = new Array(fs.length),
26                                cancel = function(){
27                                        each(results, function(v){
28                                                if(v instanceof Deferred && v.fired < 0){
29                                                        v.cancel();
30                                                }
31                                        });
32                                },
33                                x = new Deferred(cancel),
34                                ready = fs.length;
35                        each(fs, function(f, i){
36                                var x;
37                                try {
38                                        x = f(init);
39                                }catch(e){
40                                        x = e;
41                                }
42                                results[i] = x;
43                        });
44                        var failed = some(results, function(v){
45                                if(v instanceof Error){
46                                        cancel();
47                                        x.errback(v);
48                                        return true;
49                                }
50                                return false;
51                        });
52                        if(!failed){
53                                each(results, function(v, i){
54                                        if(v instanceof Deferred){
55                                                v.addCallbacks(
56                                                        function(v){
57                                                                results[i] = v;
58                                                                if(!--ready){
59                                                                        x.callback(results);
60                                                                }
61                                                        },
62                                                        function(v){
63                                                                cancel();
64                                                                x.errback(v);
65                                                        }
66                                                );
67                                        }else{
68                                                --ready;
69                                        }
70                                });
71                        }
72                        if(!ready){
73                                x.callback(results);
74                        }
75                        return x;
76                };
77        };
78
79        async.any = function(x){
80                // summary:
81                //              Executes functions in parallel. As soon as one of them finishes
82                //              cancels the rest.
83                var fs = opts.call(x) == "[object Array]" ? x : arguments;
84                return function(init){
85                        var results = new Array(fs.length), noResult = true;
86                                cancel = function(index){
87                                        each(results, function(v, i){
88                                                if(i != index && v instanceof Deferred && v.fired < 0){
89                                                        v.cancel();
90                                                }
91                                        });
92                                },
93                                x = new Deferred(cancel);
94                        each(fs, function(f, i){
95                                var x;
96                                try {
97                                        x = f(init);
98                                }catch(e){
99                                        x = e;
100                                }
101                                results[i] = x;
102                        });
103                        var done = some(results, function(v, i){
104                                if(!(v instanceof Deferred)){
105                                        cancel(i);
106                                        x.callback(v);
107                                        return true;
108                                }
109                                return false;
110                        });
111                        if(!done){
112                                each(results, function(v, i){
113                                        v.addBoth(
114                                                function(v){
115                                                        if(noResult){
116                                                                noResult = false;
117                                                                cancel(i);
118                                                                x.callback(v);
119                                                        }
120                                                }
121                                        );
122                                });
123                        }
124                        return x;
125                };
126        };
127
128        async.select = function(cond, x){
129                // summary:
130                //              Executes a condition, waits for it if necessary, and executes
131                //              Nth function from list.
132                var fs = opts.call(x) == "[object Array]" ? x : aps.call(arguments, 1);
133                return function(init){
134                        return new Deferred().addCallback(cond).addCallback(function(v){
135                                if(typeof v == "number" && v >= 0 && v < fs.length){
136                                        return fs[v](init);
137                                }else{
138                                        return new Error("async.select: out of range");
139                                }
140                        }).callback(init);
141                };
142        };
143
144        async.ifThen = function(cond, ifTrue, ifFalse){
145                // summary:
146                //              Executes a condition, waits for it if necessary, and executes
147                //              one of two functions.
148                return function(init){
149                        return new Deferred().addCallback(cond).addCallback(function(v){
150                                return (v ? ifTrue : ifFalse)(init);
151                        }).callback(init);
152                };
153        };
154
155        async.loop = function(cond, body){
156                // summary:
157                //              Executes a condition, waits for it if necessary, and executes
158                //              the body, if truthy value was returned.
159                //              Then it repeats the cycle until the condition function returns
160                //              a falsy value.
161                return function(init){
162                        var x, y = new Deferred(function(){ x.cancel(); });
163                        function ifErr(v){ y.errback(v); }
164                        function loop(v){
165                                if(v){
166                                        x.addCallback(body).addCallback(setUp);
167                                }else{
168                                        y.callback(v);
169                                }
170                                return v;
171                        }
172                        function setUp(init){
173                                x = new Deferred().
174                                        addCallback(cond).
175                                        addCallback(loop).
176                                        addErrback(ifErr);
177                                x.callback(init);
178                        }
179                        setUp(init);
180                        return y;
181                };
182        };
183})();
184
185/*
186Design decisions:
187
188seq() - behaves like the normal Deferred callback chain.
189
190par() - if error, all pending Deferreds are cancelled and the error is signaled,
191otherwise return an array of all results.
192
193any() - just like par() but only one result is returned.
194
195select() - any error is returned, otherwise the selected result is returned.
196
197loop() - any error is returned, otherwise the last result is returned.
198
199*/
Note: See TracBrowser for help on using the repository browser.