jquery Deferred使用经验
這周做了個小活動(http://aoqi.100bt.com/zt-2016duanzi/index.html),剛開始時候沒看好需求,邏輯都寫一塊了
最后各種坑要填補,從中也獲取了些經驗和教訓,下面說說這里會用到的$.Deferred;
關于jquery里面的deferred的基本使用方法,阮一峰大嬸已經有文章說明了,鏈接如下:
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html
這里就說說里面沒提及的吧:
頁面中邏輯比較麻煩的就是獲獎名單的渲染問題,如下圖
?
這里需要的邏輯是:
1、獲取時間,判斷是否有活動過了投票時間,沒有則不可點擊,頁面不渲染
2、過來時間后,判斷能否獲取到獲獎名單,獲取到就渲染次階段的頁面,獲取不到則渲染前一個階段的頁面,
前一個階段的頁面還是獲取不到則往前回溯,如果到第一個階段還是沒有則頁面不渲染。
假設四個頁面對應的獲獎名單是1.html、2.html、3.html、4.html;
假如此時有時間判斷活動時間已經在第四階段,即是前三個階段都結束,我們的實現邏輯或許是
$.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) {// 不渲染頁面 })}}) })這是很不可取的,在每個不同的階段都要嵌套一次,而且每個請求都要等上一個請求發完才發,太慢了。。。
于是就改成類似下面的
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('敬請期待');}); });能“并行”地發出多個請求,看似不錯,然后在添加點擊渲染事件,點擊不同的nav渲染已經出來的相應獲獎名單,嗯,這也是邏輯上需要的
$('.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)}); });這時候,我們只需在“并發”請求結束后調用最后一個可點的nav就完成了。。真贊
可是安裝現在這種寫法,我們并不能判斷是否已經完成了請求,或許需要維護個全局變量num,在每次fail和done再加1,當num等于需要發送的個數之后再調用函數
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){//由時間判斷出的是已經結束的標志$.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() }});} });此時就已經基本完成了此次邏輯了,但是代碼實在太糙,需要改進下,下面就用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){//由時間判斷出的是已經結束的標志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,調試之后發現有時候先執行完done,然后fail然后always然后又done,貌似這順序有些亂來了。。。
然而我們希望的是先done或者fail最后執行always。
發現原因是綁定順序導致的,于是發現了兩條路走,
第一條,把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的回調函數都寫一塊了,維護起來也開心。
但是當deferredArr里面只有一個元素的時候,發現報錯了,好尷尬,只能斷點看看,
發現always回調函數里面的arguments竟然是一個數組,第一項是請求返回的數據,第二個是返回狀態,第三個是此次請求的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){//由時間判斷出的是已經結束的標志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) })?
于是這個業務也完成了,廢話也講完了
?
轉載于:https://www.cnblogs.com/peace1/p/5594638.html
總結
以上是生活随笔為你收集整理的jquery Deferred使用经验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ”下载到itunes的软件不能同步到ip
- 下一篇: KOOM原理分析之一些基础知识