在平時寫ajax調用的過程當中,發起一個ajax調用常常是這麼寫的:ajax
$.ajax({ url:'http://www.oschina.net', success:function(data){ //處理成功的返回..... } });
今天忽然心血來潮,想改改寫法,因而:async
var jqXHR = $.ajax({ url:'http://www.oschina.net'}); jqXHR.done(function(data){ //處理成功的返回..... })
發現也是能夠的,有兩個疑問:函數
// Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = setTimeout(function() { jqXHR.abort("timeout"); }, s.timeout ); } try { state = 1; transport.send( requestHeaders, done ); } catch ( e ) { // Propagate exception as error if not done if ( state < 2 ) { done( -1, e ); // Simply rethrow otherwise } else { throw e; } } } function done(xxxx) return jqXHR;
對於第一個疑問,能夠肯定的是,jqXHR對象在返回以前,已經發起了請求。那麼若是返回jqXHR對象後,又作了不少事情,消耗了很多時間,再調用jqXHR.done()註冊回調函數,是否來不及呢?jQuery是怎麼保證回調函數被調用的呢?問題的關鍵就是jqXHR對象,它是一個Defer對象。Defer對象註冊的回調函數是根據狀態被調用的,若是註冊函數的時候,Defer對象已經resolve了,那麼相應的回調函數(done)會當即被調用,若是尚未resolve,那麼這個回調函數仍是會在resolve的時候被調用。url
好了,問題解決。.net