You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
3.1 KiB
109 lines
3.1 KiB
define([ |
|
'./util', |
|
'../errors/RequestTimeoutError', |
|
'../errors/CancelError', |
|
'../_base/array', |
|
'../has!host-browser?../_base/window:', |
|
'../has!host-browser?dom-addeventlistener?:../on:' |
|
], function(util, RequestTimeoutError, CancelError, array, win, on){ |
|
// avoid setting a timer per request. It degrades performance on IE |
|
// something fierece if we don't use unified loops. |
|
var _inFlightIntvl = null, |
|
_inFlight = []; |
|
|
|
function watchInFlight(){ |
|
// summary: |
|
// internal method that checks each inflight XMLHttpRequest to see |
|
// if it has completed or if the timeout situation applies. |
|
|
|
var now = +(new Date); |
|
|
|
// we need manual loop because we often modify _inFlight (and therefore 'i') while iterating |
|
for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){ |
|
var response = dfd.response, |
|
options = response.options; |
|
if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){ |
|
_inFlight.splice(i--, 1); |
|
watch._onAction && watch._onAction(); |
|
}else if(dfd.isReady && dfd.isReady(response)){ |
|
_inFlight.splice(i--, 1); |
|
dfd.handleResponse(response); |
|
watch._onAction && watch._onAction(); |
|
}else if(dfd.startTime){ |
|
// did we timeout? |
|
if(dfd.startTime + (options.timeout || 0) < now){ |
|
_inFlight.splice(i--, 1); |
|
// Cancel the request so the io module can do appropriate cleanup. |
|
dfd.cancel(new RequestTimeoutError('Timeout exceeded', response)); |
|
watch._onAction && watch._onAction(); |
|
} |
|
} |
|
} |
|
|
|
watch._onInFlight && watch._onInFlight(dfd); |
|
|
|
if(!_inFlight.length){ |
|
clearInterval(_inFlightIntvl); |
|
_inFlightIntvl = null; |
|
} |
|
} |
|
|
|
function watch(dfd){ |
|
// summary: |
|
// Watches the io request represented by dfd to see if it completes. |
|
// dfd: Deferred |
|
// The Deferred object to watch. |
|
// response: Object |
|
// The object used as the value of the request promise. |
|
// validCheck: Function |
|
// Function used to check if the IO request is still valid. Gets the dfd |
|
// object as its only argument. |
|
// ioCheck: Function |
|
// Function used to check if basic IO call worked. Gets the dfd |
|
// object as its only argument. |
|
// resHandle: Function |
|
// Function used to process response. Gets the dfd |
|
// object as its only argument. |
|
if(dfd.response.options.timeout){ |
|
dfd.startTime = +(new Date); |
|
} |
|
|
|
if(dfd.isFulfilled()){ |
|
// bail out if the deferred is already fulfilled |
|
return; |
|
} |
|
|
|
_inFlight.push(dfd); |
|
if(!_inFlightIntvl){ |
|
_inFlightIntvl = setInterval(watchInFlight, 50); |
|
} |
|
|
|
// handle sync requests separately from async: |
|
// http://bugs.dojotoolkit.org/ticket/8467 |
|
if(dfd.response.options.sync){ |
|
watchInFlight(); |
|
} |
|
} |
|
|
|
watch.cancelAll = function cancelAll(){ |
|
// summary: |
|
// Cancels all pending IO requests, regardless of IO type |
|
try{ |
|
array.forEach(_inFlight, function(dfd){ |
|
try{ |
|
dfd.cancel(new CancelError('All requests canceled.')); |
|
}catch(e){} |
|
}); |
|
}catch(e){} |
|
}; |
|
|
|
if(win && on && win.doc.attachEvent){ |
|
// Automatically call cancel all io calls on unload in IE |
|
// http://bugs.dojotoolkit.org/ticket/2357 |
|
on(win.global, 'unload', function(){ |
|
watch.cancelAll(); |
|
}); |
|
} |
|
|
|
return watch; |
|
});
|
|
|