淺談ajax

Ajax 回顧

最本質的 ajax 實際上是這樣的:javascript

function Ajax(){ 
    var xmlHttpReq = null;
    if (window.ActiveXObject){//IE5 IE6
        xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
    }
    else if (window.XMLHttpRequest){
        xmlHttpReq = new XMLHttpRequest();
    }
    if( xmlHttpReq != null ){
        xmlHttpReq.open("GET","/echo/xml/",true);    //採用異步方式
        xmlHttpReq.onreadystatechange=RequestCallBack; // 回調

        // get, send不出去,自覺置爲 null
        // open 裏用 post,下面才能夠 send(data)
        xmlHttpReq.send(null);
    }
    function RequestCallBack(){ //一旦readyState值改變,將會調用這個函數
        if( xmlHttpReq.readyState == 4 ){ // 依次 0,1,2,3,4
                if( xmlHttpReq.status == 200 ){
                    // xmlHttpReq.responseText;
                }
        }
    }
}

jQuery 出現後,在發出Ajax請求時,jQuery 會幫咱們肯定取得數據的最佳方式。可用的方式包括標準的 XMLHttpRequest 對象、微軟 ActiveX 的 XMLHTTP對象 或 script 標籤。java

因爲不一樣請求使用的數據傳輸方式不同,因此須要一個公共的接口與這些通訊交互。爲此,jqXHR 對象提供了這種接口在 XMLHttpRequest 對象可用的狀況下,封裝該對象的行爲;在 XMLHttpRequest 對象不可用的狀況下,則儘量模擬它。jqXHR 提供給咱們的屬性和方法包括:web

  • 包含返回數據的 .responseText或.responseXML;
  • 包含狀態碼和狀態描述的 .status和.statusText;
  • 關於HTTP頭部的 setRequestHeader/getRequestHeader;
  • 提前中斷通訊的.abort()

jQuery的全部 Ajax 方法都會有對象返回,只要把這個對象保存起來,隨後就能夠方便地使用這些屬性和方法。ajax

能夠屢次調用 .done()和.fail() 這兩個方法,根據須要添加多個處理程序。若是把調用 $.ajax() 的結果保存在一個變量中,那麼就能夠考慮代碼的可讀性,在後面再添加處理程序。promise

Promise 對象和 Deferred 對象

jQuery 1.5 之後,Ajax 函數($.ajax、$.get 及$.post)都會返回Promise 對象。Promise 對象表明一項有兩種可能結果(成 功或失敗)的任務,它還持有多個回調,出現不一樣結果時會分別觸發相應的回調。異步

使用Promise 對象的最大優點仍然在於,它能夠輕鬆從現有 Promise 對象 派生出新的 Promise 對象。分佈式

Deferred 就是 Promise!更準確地說,Deferred 是Promise 的超集,它 相比 Promise 是能夠直接觸發的。純 Promise 實例只容許添加多個調用,並且必須由其餘什麼東西來觸發這些調用。函數

它們的底層是 $.Callbacks.post

// jQuery 1.4 
    // 回調函數大而全,很臃腫
    $.get('/mydata', {
        success: onSuccess,
        failure: onFailure,
        always: onAlways
    });

    // jQuery 1.5
    // 優雅的分佈式
    var promise = $.get('/mydata');
    promise.done(onSuccess);
    promise.fail(onFailure);
    promise.always(onAlways);

jQuery 1.5 修改了 Ajax 實現。修改後全部 Ajax 函數($.ajax、$.get 及$.post)如今都會返回 Promise(承諾)對象。fetch

Promise 對象表明一項有兩種可能結果(成功或失敗)的任務,它還持有多個回調,出現不一樣結果時會分別觸發相應的回調。

簡單總結一下,Promise 對象接受 3 種回調形式:done、fail 和 progress。 執行(resolve) Promise 對象時,運行的是 done 回調;拒絕(reject) Promise 對象時,運行的是fail 回調; 對處於掛起狀態的Deferred 對象調用 notify 時,運行的是progress 回調.

得到jQuery 中的Promise 對象:或者生成一個$.Deferred 實例,或者進行一次可返回 Promise 對象的 API 調用。

$.when 及其餘能取用Promise 對象的jQuery 方法均支持非 Promise 對象做爲參數。這些非Promise 參數會被當成因相應參數位置已賦值而執行的Promise 對象來處理。

例如

$.when('foo')

會生成一個因賦值'foo'而當即執行的 Promise 對象。 再譬如

var promise = $.Deferred().resolve('bar');
$.when('foo', promise)

針對,動畫也可使用 promise,,jQuery 對象也能夠有promise 方法 所以,若是想生成一個在抓取某些數據且已完成 #loading 動畫以後執行的Promise 對象:

var fetching = $.get('/myData');
$.when(fetching, $('#loading'));

必需要在動畫開始以後再執行 $.when 生成的那個 Promise 對象。若是#loading 的動畫隊列爲空,則當即執行相應的 Promise 對象。

pipe 的原理爲: "請針對這個 Promise(getPromise) 對象給我一個回調,我會歸還一個 Promise (postPromise) 對象以表示回調運行的結果"

var getPromise = $.get('/query');

var postPromise = getPromise.pipe(function(data) { return $.post('/search', data); });

jQuery 1.8後 pipe 已經爲不推薦用法,改推爲 $.then.

相關文章
相關標籤/搜索