欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

jquery延遲對(duì)象解析

 更新時(shí)間:2016年10月26日 10:26:16   作者:y丶卿  
第一次認(rèn)識(shí)jquery延遲對(duì)象,這篇文章主要為大家詳細(xì)解析JQ延遲對(duì)象的相關(guān)概念,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

技術(shù)一般水平有限,有什么錯(cuò)的地方,望大家指正。

  ES6已經(jīng)實(shí)現(xiàn)了延遲對(duì)象Promise,但是今天主角是JQ里面的延遲對(duì)象,套路其實(shí)都是差不多的。下面先看一個(gè)比較牽強(qiáng)的例子:

<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>我是點(diǎn)擊按鈕創(chuàng)建的元素</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");
  })
})

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

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

  在看上面的這段代碼你仔細(xì)一想就會(huì)發(fā)現(xiàn)有個(gè)毛用啊,我們把改變顏色的代碼放在一個(gè)函數(shù)里面,點(diǎn)擊的時(shí)候調(diào)用這個(gè)函數(shù)不就好了,寫這么麻煩有個(gè)鳥用。其實(shí)延遲對(duì)象最多的是應(yīng)用在AJAX中。上面的代碼我們點(diǎn)擊add之后我們?cè)邳c(diǎn)擊remove然后在點(diǎn)擊add這時(shí)候發(fā)現(xiàn)這次的字沒有變成紅色,這是因?yàn)檠舆t對(duì)象的狀態(tài)變化之后就失效了,說白了就是一次性的。

延遲對(duì)象使用

  JQ為我們實(shí)現(xiàn)了延遲對(duì)象的功能,我們一般稱為Deferred或者Promise,基本上是一個(gè)東西,確切的說Promise是從Deferred中派生的一個(gè)子類。

  我們?cè)谑褂玫臅r(shí)候首先就是創(chuàng)建一個(gè)延遲對(duì)象:var dfd = new $.Deferred()。

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

  dfd在創(chuàng)建出來之后他的狀態(tài)為pending,調(diào)用resolve方法之后:dfd.resolve()它的狀態(tài)就會(huì)變?yōu)閞esolved然后會(huì)執(zhí)行dfd.done()里面的函數(shù),dfd調(diào)用reject方法之后:dfd.reject()它的狀體就會(huì)變?yōu)閞ejected然后會(huì)執(zhí)行dfd.fail()里面的方法,并且dfd對(duì)象在從pending變?yōu)閞esolved或者rejected之后就不會(huì)再發(fā)生任何變化,這也就是我們上面的代碼為什么只能在第一次點(diǎn)擊之后的文字是紅的的原因。

  我們?cè)趤砜匆豢撮_始的代碼,我們的dfd.done()中定義了字體變紅的函數(shù),在點(diǎn)擊函數(shù)執(zhí)行后dfd調(diào)用resolve,之后dfd的狀態(tài)從pending變?yōu)閞esolved會(huì)執(zhí)行done里面的方法繼而顏色變紅。

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

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

  我們?cè)邳c(diǎn)擊之后字體顏色變?yōu)榫G色了。

  另外dfd還有另外一個(gè)函數(shù)always:dfd.always(),dfd的狀態(tài)從pending變?yōu)槟膫€(gè)狀態(tài)always里面的函數(shù)都會(huì)執(zhí)行。

  dfd的每一個(gè)方法都會(huì)返回一個(gè)延遲對(duì)象,所以done,fail,always都是可以有多個(gè)的,可以直接寫成鏈?zhǔn)秸{(diào)用:

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

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

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

   第一個(gè)函數(shù)添加元素,第二個(gè)函數(shù)改變添加元素的顏色。

  無論什么時(shí)候dfd三個(gè)API里面的函數(shù)都會(huì)在dfd的狀態(tài)從pending變化之后才能執(zhí)行,在異步的情況下如此,在同步的情況下也是。更確切的說dfd在調(diào)用dfd.resolve()之后已經(jīng)執(zhí)行過的done的里面的函數(shù)會(huì)立即執(zhí)行,對(duì)于dfd.resolve()后面的done來說當(dāng)程序走到它那時(shí)才會(huì)執(zhí)行:

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

延遲對(duì)象示例

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

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

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

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

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

  已經(jīng)知道延遲對(duì)象可以改變代碼的執(zhí)行順序,假如我們又下面的代碼:

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

  我們會(huì)發(fā)現(xiàn)嵌套的有點(diǎn)多了,我們就可以利用延遲對(duì)象讓他看起來更加好看一點(diǎn):

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

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

  延遲對(duì)象的里一個(gè)作用就是可以合并AJAX的調(diào)用,比如一個(gè)接口取數(shù)據(jù)A另一個(gè)接口取數(shù)據(jù)B,AB都取到之后我們?cè)诶眠@些數(shù)據(jù)做一些喜歡做的事,我們就可以利用延遲對(duì)象輕松實(shí)現(xiàn)。此時(shí)我們就可以利用JQ的$.when()來實(shí)現(xiàn)。$.when()就跟他的名字一樣-當(dāng)什么的時(shí)候-,他的參數(shù)可以是Promise對(duì)象,也可以是字符串(很少遇到不在介紹),他的返回結(jié)果也是一個(gè)Promise對(duì)象,下面看一個(gè)小例子: 

  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是保存所有數(shù)據(jù)的一個(gè)集合,dataA是第一個(gè)AJAX返回的Promise對(duì)象,dataB是第二個(gè)。$.when()的done方法執(zhí)行的唯一條件就是dataA和dataB都執(zhí)行成功。

  補(bǔ)充:dfd還有一對(duì)組合就是notify+progress當(dāng)dfd對(duì)象的狀態(tài)處于pending時(shí)可以調(diào)用dfd.nothfy(),調(diào)用之后dfd.progress()里面的函數(shù)會(huì)執(zhí)行,只要dfd處于pending狀態(tài)dfd.notify()就可以一直調(diào)用,同樣也可以傳遞參數(shù)。

相關(guān)文章

最新評(píng)論