Ajax 回顧
最本質的 ajax 實際上是這樣的:javascript
function Ajax(){
var xmlHttpReq = null;
if (window.ActiveXObject){
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest){
xmlHttpReq = new XMLHttpRequest();
}
if( xmlHttpReq != null ){
xmlHttpReq.open("GET","/echo/xml/",true);
xmlHttpReq.onreadystatechange=RequestCallBack;
xmlHttpReq.send(null);
}
function RequestCallBack(){
if( xmlHttpReq.readyState == 4 ){
if( xmlHttpReq.status == 200 ){
}
}
}
}
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
$.get('/mydata', {
success: onSuccess,
failure: onFailure,
always: onAlways
});
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.