deferred对象和promise对象(一)
个人认为阮一峰老师讲的关于deferred对象是最容易理解的。
deferred对象是jquery的回调函数解决方案。解决了如何处理耗时操作的问题,对那些操作提供了更好的控制,以及统一的编程接口。
deferred对象的功能:
1.将ajax操作改为链式
对于$.ajax()操作完成之后,如果使用的是低于1.5版本的jquery,返回的是XHR对象,高于1.5版本返回的是deferred对象。deferred对象可进行链式操作。
$.ajax({ url:"test.html", success:function(){},//success方法指定操作成功后的回调函数 error:function(){}//error方法指定操作失败后的回调函数 }) //新的写法 $.ajax("test.html") .done(function(){})//done()相当于success方法 .failed(function(){})//failed()相当于error方法
2.指定同一操作的多个回调函数
deferred对象允许自由添加多个回调函数,回调函数按添加顺序执行
$.ajax("test.html") .done(function(){}) .failed(function(){}) .dene(function(){})//直接将多个方法加在后面
3.为多个操作指定回调函数
deferred对象允许为多个事件指定一个回调函数,利用$.when()方法
//先执行两个操作$.ajax("test1.html")和$.ajax("test2.html"),如果都成功了,就运行done()指定的回调函数;如果有一个失败或都失败了,就执行fail()指定的回调函数 $.when($.ajax("test1.html"), $.ajax("test2.html")) .done(function(){}) .fail(function(){});
4.普通操作的回调函数接口
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);
困了,今天先到这里,明天早上继续~