jquery延遲對象解析
技術(shù)一般水平有限,有什么錯的地方,望大家指正。
ES6已經(jīng)實現(xiàn)了延遲對象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>我是點擊按鈕創(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)在先聚焦功能,我們點擊add按鈕可以看到span元素添加并且顏色變紅。然后在看我們代碼中的的異類的東西,開始的var dfd = new $.Deferred();以及add事件函數(shù)中的dfd.resolve();還有就是最后面的dfd.done(function(){$("span").css("color","red");})。
$.Deferred()就是我們今天介紹的重點---JQ中的延遲對象,所謂延遲就是在以后的某段事件可以運行。我們看上面的代碼的一個處理流程,在上面的代碼中我們調(diào)用新建的延遲對象的dfd.done()方法的參數(shù)位置傳遞了一個匿名函數(shù)表達式,在點擊事件的處理函數(shù)執(zhí)行時調(diào)用dfd.resolve(),之后我們寫在dfd.done()里面的匿名函數(shù)就執(zhí)行了,在這個過程中我們可以看做,dfd把done里面的函數(shù)放在resolve的位置了。dfd就是延遲對象,很明顯它可以改變函數(shù)的執(zhí)行順序。
在看上面的這段代碼你仔細一想就會發(fā)現(xiàn)有個毛用啊,我們把改變顏色的代碼放在一個函數(shù)里面,點擊的時候調(diào)用這個函數(shù)不就好了,寫這么麻煩有個鳥用。其實延遲對象最多的是應用在AJAX中。上面的代碼我們點擊add之后我們在點擊remove然后在點擊add這時候發(fā)現(xiàn)這次的字沒有變成紅色,這是因為延遲對象的狀態(tài)變化之后就失效了,說白了就是一次性的。
延遲對象使用
JQ為我們實現(xiàn)了延遲對象的功能,我們一般稱為Deferred或者Promise,基本上是一個東西,確切的說Promise是從Deferred中派生的一個子類。
我們在使用的時候首先就是創(chuàng)建一個延遲對象:var dfd = new $.Deferred()。
延遲對象dfd有三種狀態(tài)分別為pending,resolved,rejected,我們可以通過對dfd對象使用state方法來查看此時的狀態(tài):dfd.state()。
dfd在創(chuàng)建出來之后他的狀態(tài)為pending,調(diào)用resolve方法之后:dfd.resolve()它的狀態(tài)就會變?yōu)閞esolved然后會執(zhí)行dfd.done()里面的函數(shù),dfd調(diào)用reject方法之后:dfd.reject()它的狀體就會變?yōu)閞ejected然后會執(zhí)行dfd.fail()里面的方法,并且dfd對象在從pending變?yōu)閞esolved或者rejected之后就不會再發(fā)生任何變化,這也就是我們上面的代碼為什么只能在第一次點擊之后的文字是紅的的原因。
我們在來看一看開始的代碼,我們的dfd.done()中定義了字體變紅的函數(shù),在點擊函數(shù)執(zhí)行后dfd調(diào)用resolve,之后dfd的狀態(tài)從pending變?yōu)閞esolved會執(zhí)行done里面的方法繼而顏色變紅。
dfd.resolve()和dfd.done()之間是可以進行參數(shù)傳遞的,現(xiàn)在我們對開始的代碼做一些修改:
//done里面的修改如下 dfd.done(function(color){$("span").css("color",color)}) //點擊事件的處理函數(shù)修改如下 dfd.resolve("green");
我們在點擊之后字體顏色變?yōu)榫G色了。
另外dfd還有另外一個函數(shù)always:dfd.always(),dfd的狀態(tài)從pending變?yōu)槟膫€狀態(tài)always里面的函數(shù)都會執(zhí)行。
dfd的每一個方法都會返回一個延遲對象,所以done,fail,always都是可以有多個的,可以直接寫成鏈式調(diào)用:
dfd.done(function(){}).done(function(){}).fail(function(){});
dfd的無論哪個API都可以寫多個,這時候我們就可能會考慮它的執(zhí)行順序能不能保證。這點我們完全可以放心,dfd的函數(shù)執(zhí)行的順序是完全沒有問題的按照我們書寫的順序執(zhí)行,看下面的代碼:
dfd.done(function(){ var span = $("<span>我是點擊按鈕創(chuàng)建的元素</span>"); $("span").length==0&&$("body").append(span); }) .done(function(color){ $("span").css("color",color)}); })
第一個函數(shù)添加元素,第二個函數(shù)改變添加元素的顏色。
無論什么時候dfd三個API里面的函數(shù)都會在dfd的狀態(tài)從pending變化之后才能執(zhí)行,在異步的情況下如此,在同步的情況下也是。更確切的說dfd在調(diào)用dfd.resolve()之后已經(jīng)執(zhí)行過的done的里面的函數(shù)會立即執(zhí)行,對于dfd.resolve()后面的done來說當程序走到它那時才會執(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
延遲對象示例
最開始我們使用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處理不同的事情這樣看起來比較清晰。
已經(jīng)知道延遲對象可以改變代碼的執(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... }) })
我們會發(fā)現(xià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... }) })
沒有延遲對象我們一樣能完成需要的功能,此時我們就需要一層一層嵌套我們處理過程了,而有了延遲對象我們就可以避免這種事了,他可以輕松控制代碼的執(zhí)行順序,讓代碼看起來更請清晰。你可能會說我封裝函數(shù)在合適的地方調(diào)不就行了,如果自己看自己寫的代碼沒問題,但是換一個人他的滾動條可能就一直上上下下了。
延遲對象的里一個作用就是可以合并AJAX的調(diào)用,比如一個接口取數(shù)據(jù)A另一個接口取數(shù)據(jù)B,AB都取到之后我們在利用這些數(shù)據(jù)做一些喜歡做的事,我們就可以利用延遲對象輕松實現(xiàn)。此時我們就可以利用JQ的$.when()來實現(xiàn)。$.when()就跟他的名字一樣-當什么的時候-,他的參數(shù)可以是Promise對象,也可以是字符串(很少遇到不在介紹),他的返回結(jié)果也是一個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是保存所有數(shù)據(jù)的一個集合,dataA是第一個AJAX返回的Promise對象,dataB是第二個。$.when()的done方法執(zhí)行的唯一條件就是dataA和dataB都執(zhí)行成功。
補充:dfd還有一對組合就是notify+progress當dfd對象的狀態(tài)處于pending時可以調(diào)用dfd.nothfy(),調(diào)用之后dfd.progress()里面的函數(shù)會執(zhí)行,只要dfd處于pending狀態(tài)dfd.notify()就可以一直調(diào)用,同樣也可以傳遞參數(shù)。
- jquery 延遲執(zhí)行實例介紹
- jQuery實現(xiàn)鼠標滾動圖片延遲加載效果附源碼下載
- jQuery實現(xiàn)帶延遲效果的滑動菜單代碼
- jQuery實現(xiàn)延遲跳轉(zhuǎn)的方法
- jQuery延遲加載圖片插件Lazy Load使用指南
- 使用jquery實現(xiàn)的一個圖片延遲加載插件(含圖片延遲加載原理)
- Jquery圖片延遲加載插件jquery.lazyload.js的使用方法
- jquery插件lazyload.js延遲加載圖片的使用方法
- jQuery lazyLoad圖片延遲加載插件的優(yōu)化改造方法分享
- jQuery Pagination Ajax分頁插件(分頁切換時無刷新與延遲)中文翻譯版
- Lazy Load 延遲加載圖片的jQuery插件中文使用文檔
- jquery圖片延遲加載 前端開發(fā)技能必備系列
- jQuery延遲執(zhí)行的實現(xiàn)方法
相關(guān)文章
jQuery中setTimeout的幾種使用方法小結(jié)
jQuery 中 setTimeout/setInterval 不能像在原生態(tài) javascript 中那樣使用, 否則會報錯.2013-04-04animate動畫示例(淚奔的小孩)及stop和delay的使用
實現(xiàn)原理:停止動畫,當一個元素有一個動畫隊列時,停止的是當前動畫,緊接著執(zhí)行下一個動畫,具體代碼如下,感興趣的朋友可以參考下哈,希望對你學習jquery動畫有所幫助2013-05-05詳解Jquery 遍歷數(shù)組之$().each方法與$.each()方法介紹
這篇文章主要介紹了詳解Jquery 遍歷數(shù)組之$().each方法與$.each()方法介紹 ,具有一定的參考價值,有興趣的可以了解一下。2017-01-01JQUERY 對象與DOM對象之兩者相互間的轉(zhuǎn)換
jquery對象的相應方法DOM對象不能使用,而DOM對象的相應方法jquery也不能使用。所以在具體項目中要注意Jquery對象與DOM對象的轉(zhuǎn)換問題2009-04-04使用jQuery加載html頁面到指定的div實現(xiàn)方法
下面小編就為大家?guī)硪黄褂胘Query加載html頁面到指定的div實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-07-07