这周做了个小活动(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)
})

于是这个业务也完成了,废话也讲完了

												

jquery Deferred使用经验的更多相关文章

  1. JS魔法堂:jQuery.Deferred(jQuery1.5-2.1)源码剖析

    一.前言 jQuery.Deferred作为1.5的新特性出现在jQuery上,而jQuery.ajax函数也做了相应的调整.因此我们能如下的使用xhr请求调用,并实现事件处理函数晚绑定. var p ...

  2. 深入分析,理解jQuery.Deferred源码

    前言: 如果你对jQuery.Callback回调对象不了解,或者只掌握其方法,但是没有通过阅读源码理解,可以先阅读 前一章jQuery.Callbacks源码解读二,因为只有完全理解jQuery.C ...

  3. javascript源代码学习之五——jQuery.deferred

    jQuery.Defered——异步队列用于管理一组回调函数(成功resolve,失败reject,消息progress),基于上一节实现的jQuery.callbacks完成. done,fail, ...

  4. 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise

    Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...

  5. jquery.Deferred promise解决异步回调

    我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越 ...

  6. 第三十四课:jQuery Deferred详解2

    上一课主要分析了jQuery1.51版本的jQuery Deferred.在jQuery1.6中,jQuery Deferred添加了两个方法,always,pipe. always用来添加回调,无论 ...

  7. 第三十三课:jQuery Deferred详解1

    之前我们讲了Mochikit Deferred,JSDeferred,现在讲jQuery Deferred.首先,我们先来讲下他们的区别: 在保存回调函数时,Mochikit Deferred(doj ...

  8. 使用 jQuery Deferred 和 Promise 创建响应式应用程序

    这篇文章,我们一起探索一下 JavaScript 中的 Deferred 和 Promise 的概念,它们是 JavaScript 工具包(如Dojo和MochiKit)中非常重要的一个功能,最近也首 ...

  9. 利用 Jquery Deferred 异步你的程序

    最近在做公司QA系统改造时,有这样的一个场景. QA系统中有些数据项需要从JIRA平台(一个国外项目与事务跟踪工具)中获取,JIRA平台提供了很完善的Rest API. 现在的要求是,在QA系统中提交 ...

随机推荐

  1. 第2章 Python基础语法--Hello python

    第2章 基础语法 2.1 基本介绍 2.1.1 Hello python 每个语言的开始都是从”HelloWorld”开始的,我们也不例外.打开已经安装好的Python编译环境,至于Python如何安 ...

  2. 我的Python成长之路---第八天---Python基础(23)---2016年3月5日(晴)

    socketserver 之前讲道德socket模块是单进程的,只能接受一个客户端的连接和请求,只有当该客户端断开的之后才能再接受来自其他客户端的连接和请求.当然我们也可以通过python的多线程等模 ...

  3. Identity-修改Error错误提示为中文

    第一步:重写IdentityErrorDescriber public class CustomIdentityErrorDescriber : IdentityErrorDescriber     ...

  4. 蝕刻技術(Etching Technology)

    1. 前言 蚀刻是将材料使用化学反应或物理撞击作用而移除的技术. 蚀刻技术可以分为『湿蚀刻』(wet etching)及『干蚀刻』(dry etching)两类.在湿蚀刻中是使用化学溶液,经由化学反应 ...

  5. 一个简单的基于canvas小游戏

    GDOI2016是我的退役战,不知道是题目画风不对,还是我自身的问题. 不过没关系啦,反正已经进过一次队OI生涯就没有什么遗憾的了. 这几天尝试着去做了个所谓的html5小游戏,略显简陋,但还是写个总 ...

  6. Uva 225 Golygons

    这道题如果直接用Dfs,运气好的话是可以直接过的. 但如果要在Dfs的基础上加快速度,剪枝是必不可少的. 我的剪枝策略: 1.当前点(x,y)回到出发点至少需要 |x| +| y| 步,如果剩余的步数 ...

  7. 二分图最大匹配 hdoj 1045

    题目:hdoj1045 题意:给出一个图.当中有 . 和 X 两种,. 为通路,X表示墙,在当中放炸弹,然后炸弹不能穿过墙.问你最多在图中能够放多少个炸弹? 分析:这道题目是在上海邀请赛的题目的数据简 ...

  8. [转]组合数取模 Lucas定理

    对于C(n, m) mod p.这里的n,m,p(p为素数)都很大的情况.就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了. 这里用到Lusac定理 ...

  9. excel列显示形式互换(字母与数字)

    以office2007为例: excel选项>公式>使用公式下的'R1C1引用样式' 打上钩显示形式为数字,不打钩显示形式为字母

  10. iOS5.1下emoji表情显示方框的解决办法

    在iOS5.1的部分设备上,emoji表情无法正常显示.我测试了一下,iOS5.1(9B176 for iPhone 4)无法正常显示emoji,全部是方框iOS5.1(9B179 for iPhon ...