jquery延迟(deferred)对象和回调函数详解推荐 亲测 原创 收藏


  • :
  • 03-05 21:27
  • :
  • 18次
  • :
  • 0条
  • 1赞

简介本文主要讲的是jquery里的deferred延迟对象的含义及使用方法,及回调函数的使用方法及实例。

本文站长和大家整理一下jquery里延迟对象,即deferred对象和回调函数相关的内容。

什么是延迟(deferred)对象?

在我们日常的web开发中,我们经常会用到ajax,或者遍历一组数据,这些操作都是不能马上结束,立即得到结果的,这个现象就是函数里的延迟现象,而deferred对象,也就是延迟对象,就是jquery里用来解决这种“延迟现象”回调函数的方案。

解释起来,可能大家都不会很明白,下面站长来结合具体的实例来一步步的讲解:

第1:关于jquery里的延迟对象,最常用的就是ajax了,我们知道,通常的ajax的写法如下:

$.ajax({
    url:"http://www.aijquery.cn",
    success:function(d){alert("成功了!");},
    error:function(){alert("失败了!");},
    complete:function(){alert("完成了!");}
});

1.5.0版本之前的jQuery,ajax返回的是XHR对象,但在之后的版本里,ajax返回的就是deferred对象了,而deferred对象是支持“链式”写法的,所以上面的写法等价于:

$.ajax({url:"http://www.aijquery.cn"})
    .done(function(d){alert("成功了!");})
    .fail(function(d){alert("失败了!");})
    .always(function(){alert("完成了!");});

链式写法的好处,第一就是让代码更“易读”了很多,第二,就是方便“扩展”,比如,我们可以在一次ajax成功后,附加多个回调函数:

$.ajax({url:"http://www.aijquery.cn"})
    .done(function(d){alert("成功了!");})
    .done(function(d){alert("附加的第二个回调函数");});

另外,可以把done和fail合写成then:

$.get("test.php").then(
    function(){ alert("成功了!"); },
    function(){ alert("失败了!"); }
);

有的朋友可能就要问了,就算知道了可以给ajax扩展添加多个回调函数,也没有太大的用处啊,当然是很有用处的,下面站长给大家举一个实例:

var aa=function(){
    $.ajax({url:"Do.asp"}).done(function(a){$("#aijquery").html(a);aa();});
};
aa();

上面这段代码,会让页面持续不断的一直从Do.asp里请求数据,然后显示在页面ID为"aijquery"的标签窗器里,可以被用在实时显示服务器的时间,或者类似“聊天室”的功能里。

当然,上面这段代码,大家不要轻易的尝试,因为会不间断的一支向服务器发送“请求”,很容易造成服务器的“卡死”,所以我们可以再近一步的优化一下,设定好每次“请求”的时间间隔:

var aa=function(){    
    setTimeout(function(){
        $.ajax({url:"Do.asp"}).done(function(a){$("#aijquery").html(a);aa();});
    },1000);
};
aa();

上面的这段代码就变成了每隔1000毫秒,也就是一秒的时间,向服务器发送一次ajax请求,从do.asp里获取数据。

这里只是站长列举的一个简单的实例,当然还会有很多其它的用法,比如站长在做后台的静态生成的时间,就是按这个模式来写的,在要生成网站所有的HTML页面时,就这样每隔一秒或指定时间来生成一个,这样不容易造成服务器的“卡死”。

第2:为多个ajax请求指定回调函数:

这种用法不太常用,大致的结构如下:

$.when($.ajax("a.html"), $.ajax("b.html"))
.done(function(){ alert("成功了!"); })
.fail(function(){ alert("失败了!"); });

第3:为普通的函数指定回调函数:

如果我们有一个“比较耗时”,不能“马上结束”的函数,如:

var bb=function(){
    for(var i=0;i<99999;i++){
        //do something    
    }
};

我们可以这样来给上面这个函数来添加回调函数,也就是当上面这个函数执行完后,添加要执行的操作:

按照常理,我们可能会这样来写:

$.when(bb()).done(function(){alert("循环操作完成了,可以进行下一步操作了!"); })

在逻辑上是没有问题的,但在实际中,会发现,done里的函数在循环没有完成的时候,就会执行,原因就是$.when()的参数只能是deferred对象,所以必须对bb()进行改写:

var dtd = $.Deferred(); // 新建一个deferred对象var wait = function(dtd){
var bb=function(){
  for(var i=0;i<99999;i++){
        //do something    
    }
  dtd.resolve(); // 改变deferred对象的执行状态  };
  return dtd;
};
$.when(bb()).done(function(){alert("循环操作完成了,可以进行下一步操作了!"); });

把bb()这个函数改成上面这总写法后,我们再次测试,就完全“正常”了,只有在循环完成后,才会执行done里的函数。

这时,我们就要学习和知道Deferred对象里的几个相关函数了:

resolve()  : 将dtd对象的执行状态从"未完成"改为"已完成",从而触发done()方法; 

reject() : dtd对象的执行状态从"未完成"改为"已失败",从而触发fail()方法;

另外还有一个比较抽象的:

promise() : 返回一个动态生成的Promise对象用来观察“延迟”(队列)是否已经完成。

拿上面的实例来说,因为dtd是定义在函数外面的,所以这也就表示,dtd是会受到“外部”的影响的,而如果要让我们的函数不受外部的影响,可以改成如下:

var dtd = $.Deferred(); // 新建一个deferred对象var wait = function(dtd){
var bb=function(){
  for(var i=0;i<99999;i++){
        //do something    
    }
  dtd.resolve(); // 改变deferred对象的执行状态  };
  return dtd.promise();
};
$.when(bb()).done(function(){alert("循环操作完成了,可以进行下一步操作了!"); });

上面这段实例代码,和上面的区别就是“return dtd.promise()”这一句了,上面的实例返回的是dtd对象,而dtd是定义在函数外面的,所以容易受“外部”影响,而上面这段代码,返回的是promise对象,是位于函数内部的,是不会受到“外部”的影响的。



您正在找的文章可能是: