欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

jQuery1.5中deferred對象如何使用

jQuery 1.5中deferred對象如何使用,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:空間域名、雅安服務器托管、營銷軟件、網(wǎng)站建設、范縣網(wǎng)站維護、網(wǎng)站推廣。

jQuery1.5中新增的Deferreds對象,可以將任務完成的處理方式與任務本身解耦合。這在JavaScript社區(qū)沒什么新意,因為Mochikit和Dojo兩個JS框架已經(jīng)實現(xiàn)了這個特性很長一段時間了。但是隨著Julian Aubourg對jQuery1.5中AJAX模塊的重寫,deferreds理所當然成為了內部的實現(xiàn)邏輯。使用deferreds對象,多個回調函數(shù)可以被綁定在任務完成時執(zhí)行,甚至可以在任務完成后綁定這些回調函數(shù)。這些任務可以是異步的,也可以是同步的。

更重要的是,deferreds已經(jīng)作為$.ajax()的內部實現(xiàn),所以你可以在調用AJAX時自動獲取deferreds帶來的遍歷。比如我們可以這樣綁定回調函數(shù):

// $.get, 異步的AJAX請求  var req = $.get('foo.htm').success(function (response) {      // AJAX成功后的處理函數(shù)  }).error(function () {      // AJAX失敗后處理函數(shù)  });     // 這個函數(shù)有可能在AJAX結束前調用  doSomethingAwesome();     // 添加另外一個AJAX回調函數(shù),此時AJAX或許已經(jīng)結束,或許還沒有結束  // 由于$.ajax內置了deferred的支持,所以我們可以這樣寫  req.success(function (response) {      // 這個函數(shù)會在AJAX結束后被調用,或者立即被調用如果AJAX已經(jīng)結束  });

我們不再被限制到只有一個成功,失敗或者完成的回調函數(shù)了。相反這些隨時被添加的回調函數(shù)被放置在一個先進先出的隊列中。

從上面例子看出,回調函數(shù)可以被附加到AJAX請求中(任何可觀察的任務observable task),甚至在AJAX請求已經(jīng)結束。對于代碼的組織是很好的,我們再也不用寫很長的回調函數(shù)了。這就像$.queue()遇到了pub/sub(發(fā)布訂閱機制,一般用在基于事件處理的模型中).

更深入一些,想象這樣一個場景,在一些并發(fā)的AJAX請求全部結束之后執(zhí)行一個回調函數(shù)。我可以方便的通過jQuery的函數(shù)$.when()來完成:

function doAjax() {      return $.get('foo.htm');  }     function doMoreAjax() {      return $.get('bar.htm');  }     $.when(doAjax(), doMoreAjax()).then(function () {      console.log('I fire once BOTH ajax requests have completed!');  }).fail(function () {      console.log('I fire if one or more requests failed.');  });

在jsFiddle中打開示例http://jsfiddle.net/ehynds/Mrqf8/

上面的示例能夠正常運行,這要歸功于每個jQuery的AJAX方法返回值都包含一個promise函數(shù),用來跟蹤異步請求。Promise函數(shù)的返回值是deferred對象的一個只讀視圖。(The promise is a read-only view into the result of the task.)Deferreds通過檢測對象中是否存在promise()函數(shù)來判斷當前對象是否可觀察。$.when()會等待所有的AJAX請求結束,然后調用通過 .then(), .fail()注冊的回調函數(shù)(具體調用哪些回調函數(shù)取決于任務的結束狀態(tài))。這些回調函數(shù)會按照他們的注冊順序執(zhí)行。

更好的是,$.when()接受函數(shù)或者函數(shù)的數(shù)組為參數(shù)(譯者注:這點不大對,$.when接受一個或多個deferred對象,或者原生的JS對象。注意不能以函數(shù)數(shù)組為參數(shù)),這樣你就可以隨意組合這些異步任務。

$.ajax()返回一個對象,這個對象關聯(lián)一些deferred函數(shù),比如promise(), then(), success(), error()。然而你不能操作原始的deferred對象,只有promise()函數(shù)(譯者注:還記得剛才提到的promise是只讀視圖),以及可以檢測deferred狀態(tài)的isRejected() 以及isResolved()函數(shù)。

但是為什么不返回deferred對象呢?如果返回了完整的deferred對象,那么我們就擁有更多的控制,或許可以隨意的觸發(fā)(譯者注:我把resolve翻譯成觸發(fā),就是觸發(fā)所有注冊到deferred對象上的回調函數(shù))deferred對象,從而導致所有回調函數(shù)在AJAX請求結束之前執(zhí)行。因此,為了避免不期望的觸發(fā)deferred的風險,我們應該只返回dfd.promise().(Therefore, to avoid potentially breaking the whole paradigm, only return the dfd.promise().)(譯者注:如果你很迷惑上面幾段話的確切意思,沒關系,我隨后會寫一篇文章深層次分析其中原因:http:/cnblogs.com/sanshi/)

注冊回調函數(shù)(Registering Callbacks)

上面的例子中,我們使用then(), success(), fail()方法來注冊回調函數(shù),其實還有更多的方法可以使用,特別在處理AJAX請求時。具體使用哪種方式取決于你對結果狀態(tài)的關注。

所有deferred對象都有的函數(shù) (AJAX, $.when 或者手工創(chuàng)建的deferred對象):

.then( doneCallbacks, failedCallbacks )  .done( doneCallbacks )  .fail( failCallbacks )

AJAX對象包含3個額外的方法,其中兩個會映射到上面提到的方法。這些方法主要是為了兼容以前的代碼:

// "success" 和 "error" 會分別映射到 "done" and "fail" 兩個方法  .success( doneCallbacks )  .error( failCallbacks )

你也可以注冊一個complete的回調函數(shù),它會在請求結束后調用,而不管這個請求是成功或者失敗。不像success或者error函數(shù),complete函數(shù)其實是一個單獨的deferred對象的done函數(shù)別名。這個在$.ajax()內部創(chuàng)建的deferred對象,會在AJAX結束后觸發(fā)回調函數(shù)(resolve)。

.complete( completeCallbacks )

因此,下面的3個例子是等價的(在AJAX的上下文中,success看起來比done函數(shù)會舒服點,對么?)(譯者注:其實是因為我們熟悉以前的AJAX調用方式,先入為主罷了,或者叫思維定勢):

$.get("/foo/").done( fn );  // 等價于:  $.get("/foo/").success( fn );  // 等價于:  $.get("/foo/", fn );

創(chuàng)建自己的deferred對象(Creating your own Deferred)

我們知道$.ajax和$.when在內部實現(xiàn)了deferred接口,不過我們也可以手工創(chuàng)建deferred對象:

function getData() {      return $.get('/foo/');  }     function showDiv() {      var dfd = $.Deferred();      $('#foo').fadeIn(1000, dfd.resolve);      return dfd.promise();  }     $.when(getData(), showDiv()).then(function (ajaxResult) {      console.log('The animation AND the AJAX request are both done!');      // 'ajaxResult'是服務器端返回(譯者注:也就是getData中AJAX的結果)  });

在jsFiddle中打開示例http://jsfiddle.net/ehynds/JSw5y/

在showDiv()中,我們創(chuàng)建了一個deferred對象,執(zhí)行了一段動畫,然后返回promise。這個deferred對象會在fadeIn()結束后被觸發(fā)(resolved)。在這個promise返回和deferred對象(注意:這里的deferred指的是$.when創(chuàng)建的對象,而非showDiv()返回的對象)觸發(fā)的中間,一個then()回調函數(shù)會被注冊。這個回調函數(shù)會在兩個異步的任務全部結束后執(zhí)行。

getData()返回一個對象(譯者注:其實是jQuery封裝的XMLHttpRequest對象)擁有promise方法,這就允許$.when()監(jiān)視本次AJAX請求的結束。The manually steps we took to return a promise in showDiv() is handled for us internally by $.ajax() and $.when().

1/15/2011: Julian在評論中指出,上面的語法可以被簡化為$.Deferred(fn).promise()。因此下面的兩端代碼是等價的:

function showDiv() {      var dfd = $.Deferred();      $('#foo').fadeIn(1000, dfd.resolve);      return dfd.promise();  }  // 等價于:  function showDiv() {      return $.Deferred(function (dfd) {          $('#foo').fadeIn(1000, dfd.resolve);      }).promise();  }

為自定義的deferred對象添加回調函數(shù)(Defer your Deferreds)

我們可以更進一步,為getData()和showDiv()分別注冊回調函數(shù),如同我們在$.then()中注冊回調函數(shù)一樣。(譯者注:下面的段落內容重復,說的都是一個意思,就不翻譯了,看代碼吧)

function getData() {      return $.get('/foo/').success(function () {          console.log('Fires after the AJAX request succeeds');      });  }     function showDiv() {      return $.Deferred(function (dfd) {          // 譯者注:這段代碼是原文沒有的,但是在jsFiddle中出現(xiàn)。          // 我覺得這是作者的原意,為自定義的deferred函數(shù)注冊回調函數(shù)          dfd.done(function () {              console.log('Fires after the animation succeeds');          });          $('#foo').fadeIn(1000, dfd.resolve);      }).promise();  }     $.when(getData(), showDiv()).then(function (ajaxResult) {      console.log('Fires after BOTH showDiv() AND the AJAX request succeed!');      // 'ajaxResult'是服務器返回結果  });

在jsFiddle中打開示例http://jsfiddle.net/ehynds/W3cQc/

鏈式代碼(Chaining Hotness)

Deferred的回調函數(shù)可以鏈式調用,只要函數(shù)返回的是deferred對象(譯者注:dfd.promise()返回的是只讀的deferred對象)。這是一個實際的代碼 (via @ajpiano!)

function saveContact(row) {      var form = $.tmpl(templates["contact-form"]),          valid = true,          messages = [],          dfd = $.Deferred();     /*   *   這里方式客戶端驗證代碼   */        if (!valid) {          dfd.resolve({              success: false,              errors: messages          });      } else {          form.ajaxSubmit({              dataType: "json",              success: dfd.resolve,              error: dfd.reject          });      }         return dfd.promise();  };     saveContact(row).then(function (response) {      if (response.success) {          // 客戶端驗證通過,并且保存數(shù)據(jù)成功      } else {          // 客戶端驗證失敗          // 輸出錯誤信息      }  }).fail(function (err) {      // AJAX請求失敗  });

saveContact()函數(shù)首先驗證表單數(shù)據(jù)的有效性,然后把有效性狀態(tài)保存在變量valid中。如果驗證失敗,直接deferred會被觸發(fā)(把一個包含success狀態(tài)碼和錯誤信息的JS對象作為參數(shù)傳遞給回調函數(shù))。如果驗證通過,則向服務器提交數(shù)據(jù),在AJAX成功完成后觸發(fā)deferred對象。fail()會處理404, 500等可以阻止AJAX請求成功完成的HTTP狀態(tài)碼。

不可觀察的任務(Non-observable Tasks)

Deferreds對于解耦任務與任務處理函數(shù)時非常有用,而不管是異步任務或者同步任務。一個任務可能會返回promise,但也可以返回字符串,對象或者其他類型。

在這個例子中,當“Lanch Application”鏈接被***點擊時,一個AJAX請求會發(fā)送到服務器并返回當前時間戳。然后這個時間戳會被保存到這個鏈接的data緩存中。當這個鏈接再次被點擊時,只是簡單的從緩存中取出這個時間戳返回,而不會發(fā)出AJAX請求。

function startTask(element) {      var timestamp = $.data(element, 'timestamp');         if (timestamp) {          return timestamp;      } else {          return $.get('/start-task/').success(function (timestamp) {              $.data(element, 'timestamp', timestamp);          });      }  }     $('#launchApplication').bind('click', function (event) {      event.preventDefault();         $.when(startTask(this)).done(function (timestamp) {          $('#status').html('<p>You first started this task on: ' + timestamp + '</p>');      });         loadApplication();  });

當$.when()發(fā)現(xiàn)它的***個參數(shù)沒有promise函數(shù)(因此不可觀察),它就會創(chuàng)建一個新的deferred對象,觸發(fā)deferred對象,并返回promise只讀對象。因此,任意不可觀察的任務也能傳遞到$.when()中。

需要注意的一個問題是,如果一個對象自身擁有promise函數(shù),則這個對象將不能作為deferred對象。jQuery判斷一個對象是否deferred,是通過查看它是否有promise函數(shù)來決定的,但是jQuery并不會檢查這個promise是否真的返回一個可用的對象。因此下面的代碼將會出錯:

var obj = {      promise: function () {          // do something      }  };     $.when(obj).then(fn);

結論(Conclusion)

Deferreds提出了一種新的健壯的方式來處理異步任務。和傳統(tǒng)的將代碼組織到一個回調函數(shù)中不同,新的deferred對象允許我們在任何時候(甚至在任務結束后)綁定多個回調函數(shù),而這些回調函數(shù)會以先進先出的方式被調用。這篇文章中的信息可能比較難以消化,不過一旦你掌握了deferred對象的使用,你會發(fā)現(xiàn)組織異步執(zhí)行的代碼將會非常容易。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。

當前題目:jQuery1.5中deferred對象如何使用
URL分享:http://www.chinadenli.net/article0/igpjio.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供外貿網(wǎng)站建設搜索引擎優(yōu)化網(wǎng)站策劃小程序開發(fā)服務器托管電子商務

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設