本页二维码,扫一扫分享到朋友圈
朋友圈

jQuery的deferred对象详解


阅读160 评论0 赞 43返回首页    go 编程与技术  go javascript


前言

之前在一篇文章中写过一点when方法的使用,最近看到同事的一篇文章,又详细学习了deferred方法的各种使用技巧。特此总结。


简单介绍

deferred对象就是jQuery的回调函数解决方案,jQuery之前的版本在异步回调这一块做得不是很好,所以后期加上了该解决方案。


普遍的ajax操作

我们先来回顾一下jQuery中普通的ajax操作:

1

2

3

4

5

6

7

8

9

10

$.ajax({

url:"test.html",

success:function(){

alert("哈哈,成功了!");

},

error:function(){

alert("出错啦!");

}

});

1.5版本后的新写法如下:

1

2

3

4

$.ajax("test.html")

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });

新版本的写法相比老版本有一个优势,就是可以自由添加多个回调函数,他们按照添加顺序执行:

1

2

3

4

$.ajax("test.html")

.done(function(){ alert("哈哈,成功了!");} )

.fail(function(){ alert("出错啦!"); } )

.done(function(){ alert("第二个回调函数!");} );


为多个ajax指定回调函数

我们可以通过when方法,为多个事件指定一个回调函数,这就是我之前在项目中的使用需求:

1

2

3

$.when($.ajax("test1.html"), $.ajax("test2.html"))

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });

只有当两个ajax请求都成功之后,才会运用done方法。


为普通操作指定回调函数

前面说到的when是用于ajax方法,而ajax方法其实是deferred对象,如果不是ajax方法,而是普通的函数呢?如果直接像上面一样使用when,是不会有效果的,会直接执行done方法。

所以我们需要手动新建一个deferred对象:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

vardtd = $.Deferred();// 新建一个deferred对象

varwait =function(dtd){

vartasks =function(){

alert("执行完毕!");

dtd.resolve();// 改变deferred对象的执行状态

};

setTimeout(tasks,5000);

returndtd;

};

这里的resolve就是触发done的,对应的reject方法则是用来调用fail方法的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

vardtd = $.Deferred();// 新建一个Deferred对象

varwait =function(dtd){

vartasks =function(){

alert("执行完毕!");

dtd.reject();// 改变Deferred对象的执行状态

};

setTimeout(tasks,5000);

returndtd;

};

$.when(wait(dtd))

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });


进一步优化

上面的代码有一些问题,就是dtd对象是暴露在全局的,所以我们可以通过在全局进行dtd.resolve()来提前回调。

为了避免这种情况,jQuery提供了deferred.promise()方法,它的作用是,在原来的deferred对象上返回另一个deferred对象,后者只开放与改变执行状态无关的方法(比如done方法和fail方法)屏蔽与改变执行状态有关的方法(比如resolve和reject方法)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

vardtd = $.Deferred();// 新建一个Deferred对象

varwait =function(dtd){

vartasks =function(){

alert("执行完毕!");

dtd.resolve();// 改变Deferred对象的执行状态

};

setTimeout(tasks,5000);

returndtd.promise();// 返回promise对象

};

vard = wait(dtd);// 新建一个d对象,改为对这个对象进行操作

$.when(d)

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });

d.resolve();// 此时,这个语句是无效的

当然,我们也可以把dtd包在函数内:

1

2

3

4

5

6

7

8

9

10

11

12

13

varwait =function(dtd){

vardtd = $.Deferred();//在函数内部,新建一个Deferred对象

vartasks =function(){

alert("执行完毕!");

dtd.resolve();// 改变Deferred对象的执行状态

};

setTimeout(tasks,5000);

returndtd.promise();// 返回promise对象

};

$.when(wait())

.done(function(){ alert("哈哈,成功了!"); })

.fail(function(){ alert("出错啦!"); });


  上一篇:go jQuery常用实用代码
  下一篇:go javascript代理模式与开发实践


评论


用QQ登录管理/创建网站 用微博登录管理/创建网站   发布于:11-19