0

0

jquery延迟对象解析

高洛峰

高洛峰

发布时间:2016-12-08 16:43:52

|

1106人浏览过

|

来源于php中文网

原创

技术一般水平有限,有什么错的地方,望大家指正。

  ES6已经实现了延迟对象Promise,但是今天主角是JQ里面的延迟对象,套路其实都是差不多的。下面先看一个比较牵强的例子:


    

$(function(){
  var dfd = new $.Deferred();
  var add = $("#add");
  var remove = $("#remove");
  var content = $("#content");
  add.click(function(){
    var span = $("我是点击按钮创建的元素");
    $("span").length==0&&$("body").append(span);
    dfd.resolve();
  })
  remove.click(function(){
    var span = $("span");
    span&&span.remove();
  })
  dfd.done(function(){
    $("span").css("color","red");
  })
})

   

PHP5学习对象教程
PHP5学习对象教程

PHP5学习对象教程由美国人古曼兹、贝肯、瑞桑斯编著,简张桂翻译,电子工业出版社于2007年12月1日出版的关于PHP5应用程序的技术类图书。该书全面介绍了PHP 5中的新功能、编程方法及设计模式,还分析阐述了PHP 5中新的数据库连接处理、错误处理和XML处理等机制,帮助读者系统了解、熟练掌握和高效应用PHP。

下载

  现在先聚焦功能,我们点击add按钮可以看到span元素添加并且颜色变红。然后在看我们代码中的的异类的东西,开始的var dfd = new $.Deferred();以及add事件函数中的dfd.resolve();还有就是最后面的dfd.done(function(){$("span").css("color","red");})。

  $.Deferred()就是我们今天介绍的重点---JQ中的延迟对象,所谓延迟就是在以后的某段事件可以运行。我们看上面的代码的一个处理流程,在上面的代码中我们调用新建的延迟对象的dfd.done()方法的参数位置传递了一个匿名函数表达式,在点击事件的处理函数执行时调用dfd.resolve(),之后我们写在dfd.done()里面的匿名函数就执行了,在这个过程中我们可以看做,dfd把done里面的函数放在resolve的位置了。dfd就是延迟对象,很明显它可以改变函数的执行顺序。

  在看上面的这段代码你仔细一想就会发现有个毛用啊,我们把改变颜色的代码放在一个函数里面,点击的时候调用这个函数不就好了,写这么麻烦有个鸟用。其实延迟对象最多的是应用在AJAX中。上面的代码我们点击add之后我们在点击remove然后在点击add这时候发现这次的字没有变成红色,这是因为延迟对象的状态变化之后就失效了,说白了就是一次性的。

延迟对象使用

  JQ为我们实现了延迟对象的功能,我们一般称为Deferred或者Promise,基本上是一个东西,确切的说Promise是从Deferred中派生的一个子类。

  我们在使用的时候首先就是创建一个延迟对象:var dfd = new $.Deferred()。

  延迟对象dfd有三种状态分别为pending,resolved,rejected,我们可以通过对dfd对象使用state方法来查看此时的状态:dfd.state()。

  dfd在创建出来之后他的状态为pending,调用resolve方法之后:dfd.resolve()它的状态就会变为resolved然后会执行dfd.done()里面的函数,dfd调用reject方法之后:dfd.reject()它的状体就会变为rejected然后会执行dfd.fail()里面的方法,并且dfd对象在从pending变为resolved或者rejected之后就不会再发生任何变化,这也就是我们上面的代码为什么只能在第一次点击之后的文字是红的的原因。

20161031140826605.jpg

  我们在来看一看开始的代码,我们的dfd.done()中定义了字体变红的函数,在点击函数执行后dfd调用resolve,之后dfd的状态从pending变为resolved会执行done里面的方法继而颜色变红。

  dfd.resolve()和dfd.done()之间是可以进行参数传递的,现在我们对开始的代码做一些修改:

//done里面的修改如下
dfd.done(function(color){$("span").css("color",color)})
//点击事件的处理函数修改如下
dfd.resolve("green");

   

  我们在点击之后字体颜色变为绿色了。

  另外dfd还有另外一个函数always:dfd.always(),dfd的状态从pending变为哪个状态always里面的函数都会执行。

  dfd的每一个方法都会返回一个延迟对象,所以done,fail,always都是可以有多个的,可以直接写成链式调用:

dfd.done(function(){}).done(function(){}).fail(function(){});

   dfd的无论哪个API都可以写多个,这时候我们就可能会考虑它的执行顺序能不能保证。这点我们完全可以放心,dfd的函数执行的顺序是完全没有问题的按照我们书写的顺序执行,看下面的代码:

dfd.done(function(){
  var span = $("我是点击按钮创建的元素");
  $("span").length==0&&$("body").append(span);
})
.done(function(color){
  $("span").css("color",color)});
})

   

   第一个函数添加元素,第二个函数改变添加元素的颜色。

  无论什么时候dfd三个API里面的函数都会在dfd的状态从pending变化之后才能执行,在异步的情况下如此,在同步的情况下也是。更确切的说dfd在调用dfd.resolve()之后已经执行过的done的里面的函数会立即执行,对于dfd.resolve()后面的done来说当程序走到它那时才会执行:

var dfd = new $.Deferred();
dfd.done(function(){console.log(1)});
dfd.done(function(){console.log(2)});
console.log("resolve before");
dfd.resolve();
console.log("resolve after");
dfd.done(function(){console.log(3)});
//resolve before,1,2,resolve after,3

   

延迟对象示例

  最开始我们使用JQ的AJAX的时候我们通常的写法是:

$.ajax({
 url:"x/y",
 type:"post",
 data:"{...}",
 contentType:"application/json; charset=utf-8",
 success:function(){},
 error:function(){}
})

   

  在1.5(好像是这个版本~)之后AJAX会返回一个Promise对象,继而我们可以写成下面这种:

$.ajax({
 url:"x/y",
 type:"post",
 data:"{...}",
 contentType:"application/json; charset=utf-8",
}).done(function(){})
.fail(function(){})

   

  看起来更骚气了一点,而且这我们还可以在加多个.done(function(){}),每个done处理不同的事情这样看起来比较清晰。

  已经知道延迟对象可以改变代码的执行顺序,假如我们又下面的代码:

$.ajax({
 url:"取数据",
 type:"post",
 contentType:"xxx"
}).done(function(data){
  $.ajax({
    url:"利用data取数据",
    data:data,
    type:"post",
    contentType:"xxxx"
  }).done(function(data){
    use data to _do sth...
  })
})

   

  我们会发现嵌套的有点多了,我们就可以利用延迟对象让他看起来更加好看一点:

var dfd = new $.Deferred();
$.ajax({
 url:"取数据",
 type:"post",
 contentType:"xxx"
}).done(function(data){
  dfd.resolve(data);
})
dfd.done(function(data){
  $.ajax({
    url:"利用data取数据",
    data:data,
    type:"post",
    contentType:"xxxx"
  }).done(function(data){
    use data to _do sth...
  })
})

   

  没有延迟对象我们一样能完成需要的功能,此时我们就需要一层一层嵌套我们处理过程了,而有了延迟对象我们就可以避免这种事了,他可以轻松控制代码的执行顺序,让代码看起来更请清晰。你可能会说我封装函数在合适的地方调不就行了,如果自己看自己写的代码没问题,但是换一个人他的滚动条可能就一直上上下下了。

  延迟对象的里一个作用就是可以合并AJAX的调用,比如一个接口取数据A另一个接口取数据B,AB都取到之后我们在利用这些数据做一些喜欢做的事,我们就可以利用延迟对象轻松实现。此时我们就可以利用JQ的$.when()来实现。$.when()就跟他的名字一样-当什么的时候-,他的参数可以是Promise对象,也可以是字符串(很少遇到不在介绍),他的返回结果也是一个Promise对象,下面看一个小例子: 

var allData = {};
var dataA = $.ajax({
  url:"获取A的URL",
  type:"post",
}).done(function(data){
  allData.a = data;
});
var dataB = $.ajax({
  url:"获取B的URL",
  type:"post",
}).done(function(data){
  allData.b = data;
});
$.when(dataA,dataB).done(function(){
  use allData to _do sth...
});

   

  allData是保存所有数据的一个集合,dataA是第一个AJAX返回的Promise对象,dataB是第二个。$.when()的done方法执行的唯一条件就是dataA和dataB都执行成功。

  补充:dfd还有一对组合就是notify+progress当dfd对象的状态处于pending时可以调用dfd.nothfy(),调用之后dfd.progress()里面的函数会执行,只要dfd处于pending状态dfd.notify()就可以一直调用,同样也可以传递参数。

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

22

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

24

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

99

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

132

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

15

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

63

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
jQuery 教程
jQuery 教程

共42课时 | 4.7万人学习

HTML+CSS基础与实战
HTML+CSS基础与实战

共132课时 | 9.7万人学习

tp6+adminlte搭建通用后台
tp6+adminlte搭建通用后台

共39课时 | 5.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号