diff --git a/src/ajax.js b/src/ajax.js index ca2b910dd..27abe375e 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -406,6 +406,9 @@ jQuery.extend( { // Url cleanup var urlAnchor, + // Request state (becomes false upon send and true upon completion) + completed, + // To know if global events are to be dispatched fireGlobals, @@ -435,9 +438,6 @@ jQuery.extend( { requestHeaders = {}, requestHeadersNames = {}, - // The jqXHR state - state = 0, - // Default abort message strAbort = "canceled", @@ -448,7 +448,7 @@ jQuery.extend( { // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; - if ( state === 2 ) { + if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { @@ -462,14 +462,14 @@ jQuery.extend( { // Raw string getAllResponseHeaders: function() { - return state === 2 ? responseHeadersString : null; + return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( name, value ) { - var lname = name.toLowerCase(); - if ( !state ) { - name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; requestHeaders[ name ] = value; } return this; @@ -477,7 +477,7 @@ jQuery.extend( { // Overrides response content-type header overrideMimeType: function( type ) { - if ( !state ) { + if ( completed == null ) { s.mimeType = type; } return this; @@ -487,16 +487,16 @@ jQuery.extend( { statusCode: function( map ) { var code; if ( map ) { - if ( state < 2 ) { - for ( code in map ) { - - // Lazy-add the new callback in a way that preserves old ones - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } else { + if ( completed ) { // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } } } return this; @@ -560,7 +560,7 @@ jQuery.extend( { inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // If request was aborted inside a prefilter, stop there - if ( state === 2 ) { + if ( completed ) { return jqXHR; } @@ -642,7 +642,7 @@ jQuery.extend( { // Allow custom headers/mimetypes and early abort if ( s.beforeSend && - ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { // Abort if not done already and return return jqXHR.abort(); @@ -671,7 +671,7 @@ jQuery.extend( { } // If request was aborted inside ajaxSend, stop there - if ( state === 2 ) { + if ( completed ) { return jqXHR; } @@ -683,18 +683,17 @@ jQuery.extend( { } try { - state = 1; + completed = false; transport.send( requestHeaders, done ); } catch ( e ) { - // Propagate exception as error if not done - if ( state < 2 ) { - done( -1, e ); - - // Simply rethrow otherwise - } else { + // Rethrow post-completion exceptions + if ( completed ) { throw e; } + + // Propagate others as results + done( -1, e ); } } @@ -703,13 +702,12 @@ jQuery.extend( { var isSuccess, success, error, response, modified, statusText = nativeStatusText; - // Called once - if ( state === 2 ) { + // Ignore repeat invocations + if ( completed ) { return; } - // State is "done" now - state = 2; + completed = true; // Clear timeout if it exists if ( timeoutTimer ) {