jquery Deferred使用经验
這周做了個小活動(http://aoqi.100bt.com/zt-2016duanzi/index.html),剛開始時候沒看好需求,邏輯都寫一塊了
最后各種坑要填補(bǔ),從中也獲取了些經(jīng)驗(yàn)和教訓(xùn),下面說說這里會用到的$.Deferred;
關(guān)于jquery里面的deferred的基本使用方法,阮一峰大嬸已經(jīng)有文章說明了,鏈接如下:
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html
這里就說說里面沒提及的吧:
頁面中邏輯比較麻煩的就是獲獎名單的渲染問題,如下圖
?
這里需要的邏輯是:
1、獲取時間,判斷是否有活動過了投票時間,沒有則不可點(diǎn)擊,頁面不渲染
2、過來時間后,判斷能否獲取到獲獎名單,獲取到就渲染次階段的頁面,獲取不到則渲染前一個階段的頁面,
前一個階段的頁面還是獲取不到則往前回溯,如果到第一個階段還是沒有則頁面不渲染。
假設(shè)四個頁面對應(yīng)的獲獎名單是1.html、2.html、3.html、4.html;
假如此時有時間判斷活動時間已經(jīng)在第四階段,即是前三個階段都結(jié)束,我們的實(shí)現(xiàn)邏輯或許是
$.get('3.html').done(function(){//渲染頁面 }).fail(function (argument) {$.get('2.html').done(function (argument) {//渲染頁面}).fail(function (argument) {function (argument) {$.get('1.html').done(function (argument) {// 渲染頁面}).fail(function (argument) {// 不渲染頁面 })}}) })這是很不可取的,在每個不同的階段都要嵌套一次,而且每個請求都要等上一個請求發(fā)完才發(fā),太慢了。。。
于是就改成類似下面的
var linkArr = ['1.html','2.html','3.html','4.html'] $nav.each(function(index, el) {var $self = $(this);$.get(index+'.html').done(function (argument) {$self.text('獲獎名單出來了')}).fail(function (argument) {$self.addClass('graynav').text('敬請期待');}); });能“并行”地發(fā)出多個請求,看似不錯,然后在添加點(diǎn)擊渲染事件,點(diǎn)擊不同的nav渲染已經(jīng)出來的相應(yīng)獲獎名單,嗯,這也是邏輯上需要的
$('.aCommon_nav').click(function(event) {if($(this).hasClass('graynav')){return false;}var i = $('aCommon_nav').index($(this));$.get(linkarr[i], function(data) {$inforWrap.html(data)}); });這時候,我們只需在“并發(fā)”請求結(jié)束后調(diào)用最后一個可點(diǎn)的nav就完成了。。真贊
可是安裝現(xiàn)在這種寫法,我們并不能判斷是否已經(jīng)完成了請求,或許需要維護(hù)個全局變量num,在每次fail和done再加1,當(dāng)num等于需要發(fā)送的個數(shù)之后再調(diào)用函數(shù)
var linkArr = ['1.html','2.html','3.html','4.html'] var i = 0; $nav.each(function(index, el) {var $self = $(this);if($self.attr('xxx')<=timenum){//由時間判斷出的是已經(jīng)結(jié)束的標(biāo)志$.get(index+'.html').done(function (argument) {i++;$self.text('獲獎名單出來了');if(i==LEN){//DoClickEvent() }}).fail(function (argument) {i++;$self.addClass('graynav').text('敬請期待');if(i==LEN){//DoClickEvent() }});} });此時就已經(jīng)基本完成了此次邏輯了,但是代碼實(shí)在太糙,需要改進(jìn)下,下面就用when來完成吧~
var linkArr = ['1.html','2.html','3.html','4.html'],deferredArr = []; $('.aCommon_nav').each(function(index, el) {var $self = $(this);if($self.attr('xxx')<=timenum){//由時間判斷出的是已經(jīng)結(jié)束的標(biāo)志deferredArr.push($.get(index+'.html').done(function (argument) {$self.text('獲獎名單出來了');}).fail(function (argument) {$self.addClass('graynav').text('敬請期待');})) } });$.when.apply(null,deferredArr).always(function(arg){$('.aCommon_nav:not(.garynav)').last().click(); })這時候,貌似完成了這個邏輯,but,調(diào)試之后發(fā)現(xiàn)有時候先執(zhí)行完done,然后fail然后always然后又done,貌似這順序有些亂來了。。。
然而我們希望的是先done或者fail最后執(zhí)行always。
發(fā)現(xiàn)原因是綁定順序?qū)е碌?#xff0c;于是發(fā)現(xiàn)了兩條路走,
第一條,把done和fail邏輯都寫在always里面,如下
$.when.apply(null,defferredArr).always(function(arg){$.each(arguments, function(index, val) {val.done(function (argument) {$self.text('獲獎名單出來了');}).fail(function (argument) {$self.addClass('graynav').text('敬請期待');})});$('.aCommon_nav:not(.garynav)').last().click(); })這感覺好贊,deferred的回調(diào)函數(shù)都寫一塊了,維護(hù)起來也開心。
但是當(dāng)deferredArr里面只有一個元素的時候,發(fā)現(xiàn)報錯了,好尷尬,只能斷點(diǎn)看看,
發(fā)現(xiàn)always回調(diào)函數(shù)里面的arguments竟然是一個數(shù)組,第一項(xiàng)是請求返回的數(shù)據(jù),第二個是返回狀態(tài),第三個是此次請求的deferred對象,
于是我們要加個判斷,或加個try.catch包裹著done和fail,代碼就不貼了,是在太糊弄了。
?
第二條路,使用setTimeout的黑魔法
var linkArr = ['1.html','2.html','3.html','4.html'],deferredArr = []; $('.aCommon_nav').each(function(index, el) {var $self = $(this);if($self.attr('xxx')<=timenum){//由時間判斷出的是已經(jīng)結(jié)束的標(biāo)志deferredArr.push($.get(index+'.html').done(function (argument) {$self.text('獲獎名單出來了');}).fail(function (argument) {$self.addClass('graynav').text('敬請期待');})) } });$.when.apply(null,deferredArr).always(function(arg){setTimeout(function (argument) {$('.aCommon_nav:not(.garynav)').last().click();},0) })?
于是這個業(yè)務(wù)也完成了,廢話也講完了
?
轉(zhuǎn)載于:https://www.cnblogs.com/peace1/p/5594638.html
總結(jié)
以上是生活随笔為你收集整理的jquery Deferred使用经验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ”下载到itunes的软件不能同步到ip
- 下一篇: KOOM原理分析之一些基础知识