日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

读jQuery之二十(Deferred对象)

發(fā)布時(shí)間:2023/12/4 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读jQuery之二十(Deferred对象) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Deferred對象是由 jQuery.Deferred 構(gòu)造的,jQuery.Deferred 被實(shí)現(xiàn)為簡單工廠模式。

它用來解決JS中的異步編程,它遵循 Common Promise/A 規(guī)范。實(shí)現(xiàn)此規(guī)范的還有 when.js?和 dojo。

?

$.Deferred作為新特性首次出現(xiàn)在版本1.5中,這個(gè)版本利用Deferred又完全重寫了Ajax模塊。

$.Deferred在jQuery代碼自身四處被使用,分別是promise方法、DOM ready、Ajax模塊、動(dòng)畫模塊。

這里以版本1.8.3分析,由于1.7后$.Callbacks從Deferred中抽離出去了,目前版本的deferred.js代碼不過150行,而真正$.Deferred的實(shí)現(xiàn)只有100行左右。

?

$.extend給標(biāo)示符$上掛了兩個(gè)方法,如下

jQuery.extend({Deferred: function( func ) {var tuples = [// action, add listener, listener list, final state[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],[ "notify", "progress", jQuery.Callbacks("memory") ]],...// All done!return deferred;},// Deferred helperwhen: function( subordinate /* , ..., subordinateN */ ) {var i = 0,resolveValues = core_slice.call( arguments ),length = resolveValues.length,....return deferred.promise();} });

?

$.Deferred的實(shí)現(xiàn)

  • 創(chuàng)建三個(gè)$.Callbacks對象,分別表示成功,失敗,處理中三種狀態(tài)
  • 創(chuàng)建了一個(gè)promise對象,具有state、always、then、primise方法
  • 通過擴(kuò)展primise對象生成最終的Deferred對象,返回該對象
  • ?

    $.when的實(shí)現(xiàn)

  • 接受若干個(gè)對象,參數(shù)僅一個(gè)且非Deferred對象將立即執(zhí)行回調(diào)函數(shù)
  • Deferred對象和非Deferred對象混雜時(shí),對于非Deferred對象remaining減1
  • Deferred對象總數(shù) = 內(nèi)部構(gòu)建的Deferred對象 + 所傳參數(shù)中包含的Deferred對象
  • 所傳參數(shù)中所有Deferred對象每當(dāng)resolve時(shí)remaining減1,直到為0時(shí)(所有都resolve)執(zhí)行回調(diào)
  • ?

    這就是$.Deferred和$.when的全部了,各個(gè)方法及使用稍后介紹。

    代碼閱讀中會(huì)發(fā)現(xiàn)then和when方法的實(shí)現(xiàn)最難理解,看多次,后感回味無窮,非常巧妙。then內(nèi)部會(huì)用到不同尋常的遞歸,when用到了計(jì)數(shù),每次異步成功后減一,直到為0后表示全部異步操作成功,這時(shí)才可執(zhí)行回調(diào)。

    ?

    上面提到Deferred里有3個(gè)$.Callbacks的實(shí)例,Deferred自身則圍繞這三個(gè)對象進(jìn)行更高層次的抽象。以下是Deferred對象的核心方法

    • done/fail/progress 是 callbacks.add,將回調(diào)函數(shù)存入
    • resolve/reject/notify 是 callbacks.fire,執(zhí)行回調(diào)函數(shù)(或隊(duì)列)

    ?

    下面舉一些示例看看如何使用Deferred對象。

    ?

    一、done/resolve

    function cb() {alert('success') } var deferred = $.Deferred() deferred.done(cb) setTimeout(function() {deferred.resolve() }, 3000)

    在HTTP中表示后臺返回成功狀態(tài)(如200)時(shí)使用,即請求成功后可執(zhí)行成功回調(diào)函數(shù)。

    ?

    二、fail/reject

    function cb() {alert('fail') } var deferred = $.Deferred() deferred.fail(cb) setTimeout(function() {deferred.reject() }, 3000)

    在HTTP中表示后臺返回非成功狀態(tài)時(shí)使用,即請求失敗后可執(zhí)行失敗回調(diào)函數(shù)。

    ?

    三、progress/notify

    function cb() {alert('progress') } var deferred = $.Deferred() deferred.progress(cb) setInterval(function() {deferred.notify() }, 2000)

    在HTTP中表示請求過程中使用,即請求過程中不斷執(zhí)行回調(diào)函數(shù)。這可用在文件上傳時(shí)的loading百分比或進(jìn)度條。

    ?

    四、鏈?zhǔn)讲僮?/p> function fn1() {alert('success') } function fn2() {alert('fail') } function fn3() {alert('progress') } var deferred = $.Deferred() deferred.done(fn1).fail(fn2).progress(fn3) // 鏈?zhǔn)讲僮?setTimeout(function() {deferred.resolve()//deferred.reject()//deferred.notify() }, 3000)

    這樣可以很方便了添加成功,失敗,進(jìn)度回調(diào)函數(shù)。

    ?

    五,便利函數(shù)then,一次添加成功,失敗,進(jìn)度回調(diào)函數(shù)

    function fn1() {alert('success') } function fn2() {alert('fail') } function fn3() {alert('progress') } var deferred = $.Deferred() deferred.then(fn1, fn2, fn3)

    調(diào)用then后還可以繼續(xù)鏈?zhǔn)秸{(diào)用then添加多個(gè)不同回調(diào)函數(shù),這個(gè)then也正是jQuery對?Common Promise/A 的實(shí)現(xiàn)。

    ?

    六、使用always方法為成功,失敗狀態(tài)添加同一個(gè)回調(diào)函數(shù)

    var deferred = $.Deferred() deferred.always(function() {var state = deferred.state() if ( state === 'resolved') {alert('success')} else if (state === 'rejected') {alert('fail')} }) setTimeout(function() {deferred.resolve()//deferred.reject() }, 3000)

    回調(diào)函數(shù)中可以使用deferred.state方法獲取異步過程中的最終狀態(tài),這里我調(diào)用的是deferred.resolve,因此最后的狀態(tài)是resolved,表示成功。

    ?

    七、when方法保證多個(gè)異步操作全部成功后才回調(diào)

    function fn1() {alert('done1') } function fn2() {alert('done2') } function fn3() {alert('all done') }var deferred1 = $.Deferred() var deferred2 = $.Deferred()deferred1.done(fn1) deferred2.done(fn2) $.when(deferred1, deferred2).done(fn3)setTimeout(function() {deferred1.resolve()deferred2.resolve() }, 3000)

    先后彈出了done1、done2、all done。 如果setTimeout中有一個(gè)reject了,fn3將不會(huì)被執(zhí)行。

    ?

    八、deferred.promise()方法返回只能添加回調(diào)的對象,這個(gè)對象與$.Deferred()返回的對象不同,只能done/fail/progress,不能resolve/reject/notify。即只能調(diào)用callbacks.add,沒有callbacks.fire。它是正統(tǒng)Deferred對象的閹割版。

    ?

    ?

    有了Deferred,我們使用jQuery書寫ajax的風(fēng)格可以這樣了

    $.ajax(url).done(success).progress(handling).fail(fail)

    ?

    看似和以前比較也沒什么優(yōu)點(diǎn),但它還可以添加多個(gè)回調(diào)

    $.ajax(url).done(success1).done(success2).fail(fail2).fail(fail2)

    1.5之前的則不行

    ?

    如果多個(gè)請求完成后才算成功,1.5之前的是無法解決的,現(xiàn)在則可以用$.when搞定

    var ajax1 = $.ajax(url1) var ajax2 = $.ajax(url2) $.when(ajax1, ajax2).done(success)

    ?

    如果項(xiàng)目中有一些異步問題不妨用用Derferred。

    ?

    相關(guān):

    http://jimliu.net/?p=64

    http://www.infoq.com/cn/news/2011/09/js-promise

    http://www.erichynds.com/jquery/using-deferreds-in-jquery/

    http://sitr.us/2012/07/31/promise-pipelines-in-javascript.html

    http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

    ?

    總結(jié)

    以上是生活随笔為你收集整理的读jQuery之二十(Deferred对象)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。