本文参考阮一峰的《jQuery的deferred对象详解》,主要是方便自己查阅,如果要了解deferred,建议移步原文查看。
deferred对象是JQuery 1.5.0版本开始引入的一个新功能,是提升jquery回调函数的解决方案。
$.deferred() 生成一个deferred对象
deferred.done() 指定操作成功时的回调函数
deferred.fail() 指定操作失败时的回调函数
deferred.promise() 没有参数时,返回一个新的deferred对象,该对象的运行状态无法被改变;接受参数时,作用为在参数对象上部署deferred接口
deferred.reject() 这个方法与deferred.resolve()正好相反,调用后将deferred对象的运行状态改变为“已失败”,从而立即触发fail()方法
$.when() 为多个操作指定回调函数
deferred.when() 有时为了省事,可以把done()和fail()合在一起,这就是then()方法
$.when($.ajax( "/main.php" ))
.then(successFunc, failureFunc );
deferred.always() 这个方法也是用来指定回调函数的,它的作用是不管调用deferred.resolve()还是deferred.reject(),最后总会调用该方法
$.ajax( "test.html" ) .always( function() { alert("已执行!");} );
例一:直接在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);
例二:使用deferred对象的建构函数$.Deferred()
$.Deferred(wait) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
例三:原来的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(); // 此时,这个语句是无效的
更好的写法是allenm所指出的,将dtd对象变成wait()函数的内部对象
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("出错啦!"); });
例四:为多个操作指定回调函数
$.when($.ajax("test1.html"), $.ajax("test2.html")) .done(function(){ alert("哈哈,成功了!"); }) .fail(function(){ alert("出错啦!"); });
例五:指定同一操作的多个回调函数
$.ajax("test.html") .done(function(){ alert("哈哈,成功了!");} ) .fail(function(){ alert("出错啦!"); } ) .done(function(){ alert("第二个回调函数!");} );