国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

jquery延遲對象解析

2019-11-20 08:39:47
字體:
來源:轉載
供稿:網友

技術一般水平有限,有什么錯的地方,望大家指正。

  ES6已經實現了延遲對象Promise,但是今天主角是JQ里面的延遲對象,套路其實都是差不多的。下面先看一個比較牽強的例子:

<button id="add">add</button><button id="remove">remove</button><div id="content"></div>
$(function(){  var dfd = new $.Deferred();  var add = $("#add");  var remove = $("#remove");  var content = $("#content");  add.click(function(){    var span = $("<span>我是點擊按鈕創建的元素</span>");    $("span").length==0&&$("body").append(span);    dfd.resolve();  })  remove.click(function(){    var span = $("span");    span&&span.remove();  })  dfd.done(function(){    $("span").css("color","red");  })})

  現在先聚焦功能,我們點擊add按鈕可以看到span元素添加并且顏色變紅。然后在看我們代碼中的的異類的東西,開始的var dfd = new $.Deferred();以及add事件函數中的dfd.resolve();還有就是最后面的dfd.done(function(){$("span").css("color","red");})。

  $.Deferred()就是我們今天介紹的重點---JQ中的延遲對象,所謂延遲就是在以后的某段事件可以運行。我們看上面的代碼的一個處理流程,在上面的代碼中我們調用新建的延遲對象的dfd.done()方法的參數位置傳遞了一個匿名函數表達式,在點擊事件的處理函數執行時調用dfd.resolve(),之后我們寫在dfd.done()里面的匿名函數就執行了,在這個過程中我們可以看做,dfd把done里面的函數放在resolve的位置了。dfd就是延遲對象,很明顯它可以改變函數的執行順序。

  在看上面的這段代碼你仔細一想就會發現有個毛用啊,我們把改變顏色的代碼放在一個函數里面,點擊的時候調用這個函數不就好了,寫這么麻煩有個鳥用。其實延遲對象最多的是應用在AJAX中。上面的代碼我們點擊add之后我們在點擊remove然后在點擊add這時候發現這次的字沒有變成紅色,這是因為延遲對象的狀態變化之后就失效了,說白了就是一次性的。

延遲對象使用

  JQ為我們實現了延遲對象的功能,我們一般稱為Deferred或者Promise,基本上是一個東西,確切的說Promise是從Deferred中派生的一個子類。

  我們在使用的時候首先就是創建一個延遲對象:var dfd = new $.Deferred()。

  延遲對象dfd有三種狀態分別為pending,resolved,rejected,我們可以通過對dfd對象使用state方法來查看此時的狀態:dfd.state()。

  dfd在創建出來之后他的狀態為pending,調用resolve方法之后:dfd.resolve()它的狀態就會變為resolved然后會執行dfd.done()里面的函數,dfd調用reject方法之后:dfd.reject()它的狀體就會變為rejected然后會執行dfd.fail()里面的方法,并且dfd對象在從pending變為resolved或者rejected之后就不會再發生任何變化,這也就是我們上面的代碼為什么只能在第一次點擊之后的文字是紅的的原因。

  我們在來看一看開始的代碼,我們的dfd.done()中定義了字體變紅的函數,在點擊函數執行后dfd調用resolve,之后dfd的狀態從pending變為resolved會執行done里面的方法繼而顏色變紅。

  dfd.resolve()和dfd.done()之間是可以進行參數傳遞的,現在我們對開始的代碼做一些修改:

//done里面的修改如下dfd.done(function(color){$("span").css("color",color)})//點擊事件的處理函數修改如下dfd.resolve("green");

  我們在點擊之后字體顏色變為綠色了。

  另外dfd還有另外一個函數always:dfd.always(),dfd的狀態從pending變為哪個狀態always里面的函數都會執行。

  dfd的每一個方法都會返回一個延遲對象,所以done,fail,always都是可以有多個的,可以直接寫成鏈式調用:

dfd.done(function(){}).done(function(){}).fail(function(){});

   dfd的無論哪個API都可以寫多個,這時候我們就可能會考慮它的執行順序能不能保證。這點我們完全可以放心,dfd的函數執行的順序是完全沒有問題的按照我們書寫的順序執行,看下面的代碼:

dfd.done(function(){  var span = $("<span>我是點擊按鈕創建的元素</span>");  $("span").length==0&&$("body").append(span);}).done(function(color){  $("span").css("color",color)});})

   第一個函數添加元素,第二個函數改變添加元素的顏色。

  無論什么時候dfd三個API里面的函數都會在dfd的狀態從pending變化之后才能執行,在異步的情況下如此,在同步的情況下也是。更確切的說dfd在調用dfd.resolve()之后已經執行過的done的里面的函數會立即執行,對于dfd.resolve()后面的done來說當程序走到它那時才會執行:

var dfd = new $.Deferred();dfd.done(function(){console.log(1)});dfd.done(function(){console.log(2)});console.log("resolve before");dfd.resolve();console.log("resolve after");dfd.done(function(){console.log(3)});//resolve before,1,2,resolve after,3

延遲對象示例

  最開始我們使用JQ的AJAX的時候我們通常的寫法是:

$.ajax({ url:"x/y", type:"post", data:"{...}", contentType:"application/json; charset=utf-8", success:function(){}, error:function(){}})

  在1.5(好像是這個版本~)之后AJAX會返回一個Promise對象,繼而我們可以寫成下面這種:

$.ajax({ url:"x/y", type:"post", data:"{...}", contentType:"application/json; charset=utf-8",}).done(function(){}).fail(function(){})

  看起來更騷氣了一點,而且這我們還可以在加多個.done(function(){}),每個done處理不同的事情這樣看起來比較清晰。

  已經知道延遲對象可以改變代碼的執行順序,假如我們又下面的代碼:

$.ajax({ url:"取數據", type:"post", contentType:"xxx"}).done(function(data){  $.ajax({    url:"利用data取數據",    data:data,    type:"post",    contentType:"xxxx"  }).done(function(data){    use data to _do sth...  })})

  我們會發現嵌套的有點多了,我們就可以利用延遲對象讓他看起來更加好看一點:

var dfd = new $.Deferred();$.ajax({ url:"取數據", type:"post", contentType:"xxx"}).done(function(data){  dfd.resolve(data);})dfd.done(function(data){  $.ajax({    url:"利用data取數據",    data:data,    type:"post",    contentType:"xxxx"  }).done(function(data){    use data to _do sth...  })})

  沒有延遲對象我們一樣能完成需要的功能,此時我們就需要一層一層嵌套我們處理過程了,而有了延遲對象我們就可以避免這種事了,他可以輕松控制代碼的執行順序,讓代碼看起來更請清晰。你可能會說我封裝函數在合適的地方調不就行了,如果自己看自己寫的代碼沒問題,但是換一個人他的滾動條可能就一直上上下下了。

  延遲對象的里一個作用就是可以合并AJAX的調用,比如一個接口取數據A另一個接口取數據B,AB都取到之后我們在利用這些數據做一些喜歡做的事,我們就可以利用延遲對象輕松實現。此時我們就可以利用JQ的$.when()來實現。$.when()就跟他的名字一樣-當什么的時候-,他的參數可以是Promise對象,也可以是字符串(很少遇到不在介紹),他的返回結果也是一個Promise對象,下面看一個小例子: 

  var allData = {};  var dataA = $.ajax({    url:"獲取A的URL",    type:"post",  }).done(function(data){    allData.a = data;  });  var dataB = $.ajax({    url:"獲取B的URL",    type:"post",  }).done(function(data){    allData.b = data;  });  $.when(dataA,dataB).done(function(){    use allData to _do sth...  });

  allData是保存所有數據的一個集合,dataA是第一個AJAX返回的Promise對象,dataB是第二個。$.when()的done方法執行的唯一條件就是dataA和dataB都執行成功。

  補充:dfd還有一對組合就是notify+progress當dfd對象的狀態處于pending時可以調用dfd.nothfy(),調用之后dfd.progress()里面的函數會執行,只要dfd處于pending狀態dfd.notify()就可以一直調用,同樣也可以傳遞參數。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鹤峰县| 黔江区| 堆龙德庆县| 宜君县| 长武县| 定安县| 新竹市| 南京市| 且末县| 新龙县| 界首市| 渭南市| 皋兰县| 遵义市| 东丰县| 菏泽市| 宿迁市| 梁河县| 宽甸| 漳州市| 潜江市| 得荣县| 平利县| 新宾| 高雄市| 荆州市| 新田县| 神农架林区| 卓尼县| 扎赉特旗| 梅州市| 长葛市| 山阳县| 平南县| 昭通市| 延庆县| 黄浦区| 华安县| 宜城市| 黄山市| 响水县|