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)
})

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

				
时间: 2024-12-29 11:31:48

jquery Deferred使用经验的相关文章

jquery Deferred

jquery Deferred使用经验 这周做了个小活动(http://aoqi.100bt.com/zt-2016duanzi/index.html),刚开始时候没看好需求,逻辑都写一块了 最后各种坑要填补,从中也获取了些经验和教训,下面说说这里会用到的$.Deferred: 关于jquery里面的deferred的基本使用方法,阮一峰大婶已经有文章说明了,链接如下: http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_o

javascript --- jQuery --- Deferred对象

javascript --- jQuery --- Deferred对象 javascript的函数式编程是多么引人入胜,jQuery使代码尽可能的精简,intelligent! defer - 必应词典:v.迁延:听从:扣存:[军]使延期入伍所以deferred对象的含义就是"延迟"到未来某个点再执行. jQuery的官方文档给出了用jQuery.ajax()发送请求的基本方式http://api.jquery.com/jQuery.ajax/Example: Save some d

jquery.Deferred promise解决异步回调

我们先来看一下编写AJAX编码经常遇到的几个问题: 1.由于AJAX是异步的,所有依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套,ajax等异步操作越多,嵌套层次就会越深,代码可读性就会越差. $.ajax({ url: url, data: dataObject, success: function(){ console.log("I depend on ajax result."); }, error: function(){} }); consol

前端学习——JQuery Ajax使用经验

0.前言 在项目推进过程中经常使用Ajax,通过Jquery提供的函数可以非常方便的使用Ajax,但是在实际使用中也遇到一些问题,例如如何防止浏览器使用缓存,如何使用同步方式等.通过博文整理总结希望自身有所提高. 在这里通过一个加法例子说明问题.为了突出ajax,前端网页和后端PHP程序尽可能的简单. [前端]--add.html 图1 add页面 [后端]--add.php <?php // 返回JSON格式 header('Content-Type:application/json;char

jQuery异步框架探究2:jQuery.Deferred方法

(本文针对jQuery1.6.1版本)关于Deferred函数的描述中有一个词是fledged,意为"羽翼丰满的",说明jQuery.Deferred函数应用应该更成熟.这个函数与jQuery._Deferred函数有密不可分的关系. 1 内部实现 Deferred: function( func ) { var deferred = jQuery._Deferred(), failDeferred = jQuery._Deferred(), promise; // Add error

第三十三课:jQuery Deferred

之前我们讲了Mochikit Deferred,JSDeferred,现在讲jQuery Deferred.首先,我们先来讲下他们的区别: 在保存回调函数时,Mochikit Deferred(dojo Deferred)是用一个2维数组保存的,里面的小数组只有两项,一个是成功回调的函数,一个是失败回调的函数. JSDeferred则每个实例都必有ng,ok这两个回调函数. jQuery Deferred则一个_Deferred负责添加成功回调,一个负责添加错误回调. 它们的API区别如下图:

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

一.前言 jQuery.Deferred作为1.5的新特性出现在jQuery上,而jQuery.ajax函数也做了相应的调整.因此我们能如下的使用xhr请求调用,并实现事件处理函数晚绑定. var promise = $.getJSON('dummy.js') // 其他逻辑处理 promise.then(function(){ alert('late binding') }) 我还一度以为这就是Promises/A+规范的实现,但其实jQuery.Deferred应该与jsDeferred归为

jquery deferred done then区别

jquery deferred done then区别 deferred是jquery 对promise的实现. 以下内容基于jquery 1.8及以上版本 deferred具有then done等属性.其区别在于Deferred resolved时, done返回当前的的deferred object,callback的返回值不会被传递 then返回一个新的deferred object,callback的返回值会被传递(参考jquery的pipe属性)给新的callback 通过以下的例子来

javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式

我们先来看一下编写AJAX编码常常遇到的几个问题: 1.因为AJAX是异步的,全部依赖AJAX返回结果的代码必需写在AJAX回调函数中.这就不可避免地形成了嵌套.ajax等异步操作越多,嵌套层次就会越深.代码可读性就会越差. $.ajax({ url: url, data: dataObject, success: function(){ console.log("I depend on ajax result."); }, error: function(){} }); consol