[483] | 1 | define([ |
---|
| 2 | './util', |
---|
| 3 | '../errors/RequestTimeoutError', |
---|
| 4 | '../errors/CancelError', |
---|
| 5 | '../_base/array', |
---|
| 6 | '../has!host-browser?../_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 | }); |
---|