]>
Commit | Line | Data |
---|---|---|
f0cfe83e AD |
1 | define("dojo/request/watch", [ |
2 | './util', | |
3 | '../errors/RequestTimeoutError', | |
4 | '../errors/CancelError', | |
5 | '../_base/array', | |
6 | '../_base/window', | |
7 | '../has!host-browser?dom-addeventlistener?:../on:' | |
8 | ], function(util, RequestTimeoutError, CancelError, array, win, on){ | |
9 | // avoid setting a timer per request. It degrades performance on IE | |
10 | // something fierece if we don't use unified loops. | |
11 | var _inFlightIntvl = null, | |
12 | _inFlight = []; | |
13 | ||
14 | function watchInFlight(){ | |
15 | // summary: | |
16 | // internal method that checks each inflight XMLHttpRequest to see | |
17 | // if it has completed or if the timeout situation applies. | |
18 | ||
19 | var now = +(new Date); | |
20 | ||
21 | // we need manual loop because we often modify _inFlight (and therefore 'i') while iterating | |
22 | for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){ | |
23 | var response = dfd.response, | |
24 | options = response.options; | |
25 | if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){ | |
26 | _inFlight.splice(i--, 1); | |
27 | watch._onAction && watch._onAction(); | |
28 | }else if(dfd.isReady && dfd.isReady(response)){ | |
29 | _inFlight.splice(i--, 1); | |
30 | dfd.handleResponse(response); | |
31 | watch._onAction && watch._onAction(); | |
32 | }else if(dfd.startTime){ | |
33 | // did we timeout? | |
34 | if(dfd.startTime + (options.timeout || 0) < now){ | |
35 | _inFlight.splice(i--, 1); | |
36 | // Cancel the request so the io module can do appropriate cleanup. | |
37 | dfd.cancel(new RequestTimeoutError('Timeout exceeded', response)); | |
38 | watch._onAction && watch._onAction(); | |
39 | } | |
40 | } | |
41 | } | |
42 | ||
43 | watch._onInFlight && watch._onInFlight(dfd); | |
44 | ||
45 | if(!_inFlight.length){ | |
46 | clearInterval(_inFlightIntvl); | |
47 | _inFlightIntvl = null; | |
48 | } | |
49 | } | |
50 | ||
51 | function watch(dfd){ | |
52 | // summary: | |
53 | // Watches the io request represented by dfd to see if it completes. | |
54 | // dfd: Deferred | |
55 | // The Deferred object to watch. | |
56 | // response: Object | |
57 | // The object used as the value of the request promise. | |
58 | // validCheck: Function | |
59 | // Function used to check if the IO request is still valid. Gets the dfd | |
60 | // object as its only argument. | |
61 | // ioCheck: Function | |
62 | // Function used to check if basic IO call worked. Gets the dfd | |
63 | // object as its only argument. | |
64 | // resHandle: Function | |
65 | // Function used to process response. Gets the dfd | |
66 | // object as its only argument. | |
67 | if(dfd.response.options.timeout){ | |
68 | dfd.startTime = +(new Date); | |
69 | } | |
70 | ||
71 | if(dfd.isFulfilled()){ | |
72 | // bail out if the deferred is already fulfilled | |
73 | return; | |
74 | } | |
75 | ||
76 | _inFlight.push(dfd); | |
77 | if(!_inFlightIntvl){ | |
78 | _inFlightIntvl = setInterval(watchInFlight, 50); | |
79 | } | |
80 | ||
81 | // handle sync requests separately from async: | |
82 | // http://bugs.dojotoolkit.org/ticket/8467 | |
83 | if(dfd.response.options.sync){ | |
84 | watchInFlight(); | |
85 | } | |
86 | } | |
87 | ||
88 | watch.cancelAll = function cancelAll(){ | |
89 | // summary: | |
90 | // Cancels all pending IO requests, regardless of IO type | |
91 | try{ | |
92 | array.forEach(_inFlight, function(dfd){ | |
93 | try{ | |
94 | dfd.cancel(new CancelError('All requests canceled.')); | |
95 | }catch(e){} | |
96 | }); | |
97 | }catch(e){} | |
98 | }; | |
99 | ||
100 | if(win && on && win.doc.attachEvent){ | |
101 | // Automatically call cancel all io calls on unload in IE | |
102 | // http://bugs.dojotoolkit.org/ticket/2357 | |
103 | on(win.global, 'unload', function(){ | |
104 | watch.cancelAll(); | |
105 | }); | |
106 | } | |
107 | ||
108 | return watch; | |
109 | }); |