什么是deferred对象
在开发过程中,经常会遇到ajax请求,或者大数据处理的情况,请求的数据或处理结果不会马上返回,通常的做法就是需要设置一个回调callback来执行完成后的操作。
deferred操作就是jquery或zepto回调函数解决方案。
它解决了耗时操作的问题,对那些操作的方法起到了更好的控制,并且有了统一的接口。
介绍一下deffered的参数
- $.Deferred() 生成一个deferred对象。
- deferred.done() 指定操作成功时的回调函数
- deferred.fail() 指定操作失败时的回调函数
- deferred.promise() 没有参数时,返回一个新的deferred对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署deferred接口。
- deferred.resolve() 手动改变deferred对象的运行状态为"已完成",从而立即触发done()方法。
- deferred.reject() 这个方法与deferred.resolve()正好相反,调用后将deferred对象的运行状态变为"已失败",从而立即触发fail()方法。
- $.when() 为多个操作指定回调函数。
- deferred.then()有时为了省事,可以把done()和fail()合在一起写,这就是then()方法。
$.when($.ajax( "/main.html" )).then(successFunc, failureFunc );
如果then()有两个参数,那么第一个参数是done()方法的回调函数,第二个参数是fail()方法的回调方法。如果then()只有一个参数,那么等同于done()。
9.deferred.always()这个方法也是用来指定回调函数的,它的作用是,不管调用的是deferred.resolve()还是deferred.reject(),最后总是执行。
.always( function() { alert("已执行!");} );```
普通耗时请求 setTimeout
console.log("执行二");```
假如想让上面的代码顺序执行,怎么做呢?普通方式是把后面执行的内容也同时包裹在setTimout里面,但是用deffered就不同了。它是通过一个包裹接口,等前置任务执行完成再进行下一步的操作。
``` var wait2 = function(){ var tasks = function(){
alert("执行完毕test!"); };
setTimeout(tasks,5000); };
$.when(wait2()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); ```
上面的方法还是会先执行done或fail里的函数,使用defferred的改写方法如下:
``` function wait(){ var dtd = $.Deferred(); // 新建一个Deferred对象
setTimeout(function(){ console.log("执行任务1");
dtd.resolve("1任务");// 改变Deferred对象的执行状态 },100); return dtd.promise(); };
wait().done(function(data){ console.log(data+"执行完成了"); });```
还有另外一种写法
```var dtd1 = $.Deferred(); // 新建一个Deferred对象 var wait1=function(dtd){
setTimeout(function(){
console.log("执行任务2");
dtd1.resolve("2任务");// 改变Deferred对象的执行状态
},100); };
dtd1.promise(wait1);
wait1.done(function(data){
console.log(data+"执行完成了"); });
wait1(dtd1);```
### ajax请求的写法老版本不支持deffered方法
``` $.ajax({ url: "test.html",
success: function(){ alert("哈哈,成功了!"); },
error:function(){ alert("出错啦!"); } });```
$.ajax()操作完成后,高于1.5.0版本,返回的是deferred对象,可以进行链式操作。
``` $.ajax("test.html")
.done(function(){ alert("哈哈,成功了!"); })
.fail(function(){ alert("出错啦!"); }); ```
deferred对象的一大好处,就是它允许你自由添加多个回调函数。``` $.ajax("test.html")
.done(function(){ alert("哈哈,成功了!");} )
.fail(function(){alert("出错啦!");} )
.done(function(){ alert("第二个回调函数!");} )
.fail(function(){ alert("真的不好意思!"); } )```
deferred对象的另一大好处,就是它允许你为多个事件指定一个回调函数,这是传统写法做不到的。
``` $.when($.ajax("test1.html"),
$.ajax("test2.html"))
.done(function(){ alert("哈哈,成功了!"); })
.fail(function(){ alert("出错啦!"); }); ```
jquery从1.5.0开始具有了deffered功能 ,zepto使用deffered的时候需要引入两个插件"deferred","callbacks",把它放入zepto内容的最低部,就OK
参考文章 [阮一峰的Deffered文章](http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html),[zepto 1.1.6 api](http://www.css88.com/doc/zeptojs_api/)