简单说,deferred对象就是jQuery的回调函数解决方案。在英语中,defer的意思是"延迟",所以deferred对象的含义就是"延迟"到未来某个点再执行。
deferred对象的最大优点,就是它把这一套回调函数接口,从ajax操作扩展到了所有操作。也就是说,任何一个操作----不管是ajax操作还是本地操作,也不管是异步操作还是同步操作----都可以使用deferred对象的各种方法,指定回调函数
1、结合jq中Deferred的promise()方法,promise()的作用是让deferred的执行状态只在deferred内部建立的基础上改变状态,通俗说,如果不设置promise()在全局中东能改变deferred的状态。
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(){
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("出错啦!"); });
上面代码中先说明下resolve、done、fail
方法,它的作用就是改变函数执行的一个状态,从函数的“未完成”状态改变成为“已完成”状态就执行done()
。有了“已完成”那就是也有“已失败”的状态,“已失败”的状态就是由reject()
方法来改变,失败后执行fail()
。
注:这两种方法其实和ES6当中提供的Promise()方法中的resolve和reject是一样的意思。
注:always()方法不管状态是失败还是成功都会执行 $.when(wait()).always()
2、使用deferred对象的建构函数 $.Deferred()
。这时,wait函数还是保持不变,我们直接把它传入Deferred():
var wait = function(dtd){
var tasks = function(){
alert("执行完毕!");
dtd.resolve(); // 改变Deferred对象的执行状态
};
setTimeout(tasks,5000);
return dtd.promise();
};
$.Deferred(wait)
.done(function(){ alert("哈哈,成功了!"); })
.fail(function(){ alert("出错啦!"); });
3、为了省事儿和解决恐怖回调问题的写法
$.when($.ajax( "/main.php" ))
.then(successFunc, failureFunc );。
上面代码中then()里面第一个参数相当于done(),第二个相当于fail()
在$.ajax当中也可以使用deferred对象的done()和fail()方法,例如:
$.ajax("test.html")
.done(function(){ alert("哈哈,成功了!");} )
.fail(function(){ alert("出错啦!"); } )
友情提示:$.Deferred()是在jQuery 1.5.0版本后使用,如果想兼容IE8,那么请选择jQuery 1.5.0~jQuery 1.9.0的版本
## 简单写一个deferred用法的例子:
function fn1(){
var deferred = $.Deferred();
setTimeout(function(){
deferred.resolve();
}, 1000);
return deferred.promise();
}
function fn2(){
var deferred = $.Deferred();
setTimeout(function(){
deferred.resolve();
}, 1000);
return deferred.promise();
}
$.when(fn1(), fn2()).done(function(){
console.log('success'); // 都resolve() success
}).fail(function(){
console.log('error'); // 有一个reject() error
});