這次帶給大家jquery延遲物件使用案例,jquery延遲物件使用的注意事項有哪些,下面就是實戰案例,一起來看一下。
技術一般水準有限,有什麼錯的地方,望大家指正。
ES6已經實現了延遲對象Promise,但是今天主角是JQ裡面的延遲對象,套路其實都是差不多的。下面先看一個比較牽強的例子:
<button id="add">add</button><button id="remove">remove</button> <p id="content"></p>
$(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()就可以一直调用,同样也可以传递参数。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是jquery延遲物件使用案例的詳細內容。更多資訊請關注PHP中文網其他相關文章!