我的认为阮一峰老师讲的关于deferred对象是最容易理解的。javascript
deferred对象是jquery的回调函数解决方案。解决了如何处理耗时操做的问题,对那些操做提供了更好的控制,以及统一的编程接口。html
deferred对象的功能:java
1.将ajax操做改成链式jquery
对于$.ajax()操做完成以后,若是使用的是低于1.5版本的jquery,返回的是XHR对象,高于1.5版本返回的是deferred对象。deferred对象可进行链式操做。ajax
$.ajax({ url:"test.html", success:function(){},//success方法指定操做成功后的回调函数 error:function(){}//error方法指定操做失败后的回调函数 }) //新的写法 $.ajax("test.html") .done(function(){})//done()至关于success方法 .failed(function(){})//failed()至关于error方法
2.指定同一操做的多个回调函数编程
deferred对象容许自由添加多个回调函数,回调函数按添加顺序执行api
$.ajax("test.html") .done(function(){}) .failed(function(){}) .dene(function(){})//直接将多个方法加在后面
3.为多个操做指定回调函数promise
deferred对象容许为多个事件指定一个回调函数,利用$.when()方法函数
//先执行两个操做$.ajax("test1.html")和$.ajax("test2.html"),若是都成功了,就运行done()指定的回调函数;若是有一个失败或都失败了,就执行fail()指定的回调函数 $.when($.ajax("test1.html"), $.ajax("test2.html")) .done(function(){}) .fail(function(){});
4.普通操做的回调函数接口url
deferred对象将回调函数的接口从ajax操做扩展到了全部操做。$.when()的参数只能是deferred对象
var wait = function(){ alertvar tasks = function(){ alert("执行完毕!"); }; setTimeout(tasks,5000); };
为wai函数添加回调函数
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.reject(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd; }; $.when(wait(dtd)) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
存在问题:dtd是全局变量,容易被修改,解决办法:jquery的deferred.promise()方法。在原来的deferred对象上返回另外一个deferred对象,后者只开放与改变执行状态无关的方法(好比done()方法和fail()方法),屏蔽与改变执行状态有关的方法(好比resolve()方法和reject()方法),从而使得执行状态不能被改变。
第一种方法:
var dtd = $.Deferred(); // 新建一个Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象
};
var d = wait(dtd); // 新建一个d对象,改成对这个对象进行操做 $.when(d) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); d.resolve(); // 此时,这个语句是无效的
第二种方法
var wait = function(dtd){ var dtd = $.Deferred(); //在函数内部,新建一个Deferred对象 var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); return dtd.promise(); // 返回promise对象 }; $.when(wait()) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
第三种方法:使用deferred对象的构造函数$.Deferred()
$.Deferred(wait) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); //jQuery规定,$.Deferred()能够接受一个函数名(注意,是函数名)做为参数,$.Deferred()所生成的deferred对象将做为这个函数的默认参数。
第四种方法:在wait方法上直接部署deferred对象
var dtd = $.Deferred(); // 生成Deferred对象 var wait = function(dtd){ var tasks = function(){ alert("执行完毕!"); dtd.resolve(); // 改变Deferred对象的执行状态 }; setTimeout(tasks,5000); }; dtd.promise(wait); wait.done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); }); wait(dtd);
困了,今天先到这里,明天早上继续~