亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

章節
問答
課簽
筆記
評論
占位
占位

Ajax的deferred實現

在異步機制這章我們詳細的分析了 deferred 的設計,其中提供了 deferred.promise 方法就是把普通對象轉化成 deferred 對象了,ajax 就是把 deferred 對象給摻進去可以讓整個 Ajax 方法變成了一個 deferred 對象,在Ajax方法中返回的是 jqXHR 一個包裝對象,在這個對象里面混入了所有實現方法。

ajax: function(url, options) {
    var jqXHR = {} //ajax對象
    deferred = jQuery.Deferred()
    //轉成deferred對象
    deferred.promise(jqXHR).complete = completeDeferred.add
    return jqXHR
}

jQuery.ajax 的版本迭代:

  • 從 jQuery 1.5 開始,$.ajax() 返回 XMLHttpRequest(jqXHR)對象,該對象是瀏覽器的原生的 XMLHttpRequest 對象的一個超集。例如,它包含 responseText 和 responseXML 屬性,以及一個 getResponseHeader() 方法。當傳輸機制不是 XMLHttpRequest 時(例如,一個 JSONP 請求腳本,返回一個腳本 tag 時),jqXHR 對象盡可能的模擬原生的 XHR 功能。
  • 從 jQuery 1.5.1 開始, jqXHR 對象還包含了overrideMimeType 方法 (它在 jQuery 1.4.x 中是有效的,但是在 jQuery 1.5 中暫時的被移除)。.overrideMimeType() 方法可能用在 beforeSend() 的回調函數中,例如,修改響應的 Content-Type 信息頭:
  • 為了讓回調函數的名字統一,便于在$.ajax()中使用。jqXHR也提供.error() .success()和.complete()方法。這些方法都帶有一個參數,該參數是一個函數,此函數在 $.ajax()請求結束時被調用,并且這個函數接收的參數,與調用 $.ajax()函數時的參數是一致。這將允許你在一次請求時,對多個回調函數進行賦值,甚至允許你在請求已經完成后,對回調函數進行賦值(如果該請求已經完成,則回調函數會被立刻調用)。

為了向后兼容 XMLHttpRequest ,jqXHR 對象將公開下列屬性和方法:

readyState
status
statusText
responseXML and/or responseText 當底層的請求分別作出XML和/或文本響應
setRequestHeader(name, value) 從標準出發,通過替換舊的值為新的值,而不是替換的新值到舊值
getAllResponseHeaders()
getResponseHeader()
abort()


為了實現以上這些功能,jQuery 在對 jqXHR 做2個處理:

  1. 異步隊列 deferred
  2. 回調隊列 Callbacks
// Deferreds
deferred = jQuery.Deferred(),
//所有的回調隊列,不管任何時候增加的回調保證只觸發一次
completeDeferred = jQuery.Callbacks("once memory"),

給 jqXHR 擴充添加 promise 的屬性和方法,然后添加 complete 方法,這里用的是回調列表的 add 方法(即添加回調)

deferred.promise(jqXHR).complete = completeDeferred.add;

此時的 jqXHR 就具有了 promise 的一些特性了與 callback 的回調列隊了,當然這里有個重點,返回了一個只讀的 deferred 對象,如果返回完整的 deferred 對象,那么外部程序就能隨意的觸發 deferred 對象的回調函數,很有可能在 AJAX 請求結束前就觸發了回調函數(resolve),這就是與 AJAX 本身的邏輯相違背了。所以為了避免不經意間改變任務的內部流程,我們應該只返回 deferred 的只讀版本 deferred.promise(),然后把對應的 done 與 fail 改成別名 success 與 error。

jqXHR.success = jqXHR.done;
jqXHR.error   = jqXHR.fail

 

我們還需要把用戶自定的內部回調函數給注冊到 jqXHR 對象上。

// 增加回調隊列
for (i in {
    success  : 1,
    error    : 1,
    complete : 1
}) {
    /**
     * 把參數的回調函數注冊到內部jqXHR對象上,實現統一調用
     * 給ajax對象注冊 回調函數add
     * deferred返回complete,error外部捕獲
     */
    jqXHR[i](s[i]);
}

通過一個 for 循環把對應的方法都執行了,具體就是這幾個:

  1. jqXHR.success(s.success)  -> jqXHR.done -> jQuery.Callbacks("once memory")
  2. jqXHR.error(s.error)  -> jqXHR.fail -> jQuery.Callbacks("once memory")
  3. jqXHR.complete(s.complete) -> jQuery.Callbacks("once memory").add(s.success

 

我們參考右邊 Ajax 的模擬實現代碼。

 

任務

?不會了怎么辦
||

提問題

寫筆記

公開筆記
提交
||

請驗證,完成請求

由于請求次數過多,請先驗證,完成再次請求

加群二維碼

打開微信掃碼自動綁定

您還未綁定服務號

綁定后可得到

  • · 粉絲專屬優惠福利
  • · 大咖直播交流干貨
  • · 課程更新,問題答復提醒
  • · 賬號支付安全提醒

收藏課程后,能更快找到我哦~

使用 Ctrl+D 可將課程添加到書簽

邀請您關注公眾號
關注后,及時獲悉本課程動態

舉報

0/150
提交
取消
全部 精華 我要發布
全部 我要發布
最熱 最新
只看我的

手記推薦

更多

本次提問將花費2個積分

你的積分不足,無法發表

為什么扣積分?

本次提問將花費2個積分

繼續發表請點擊 "確定"

為什么扣積分?