jQuery在1.5之后引进了Deferred对象,主要是对操作时间很长的方法回调提供一个简单、直观的解决方案。
之前,对时间较长的操作通常使用回调,单个回调还可以接受,但如果嵌套回调的话就有些蛋疼了。
demo
$.getJSON('/main/some/',{},function(data){
$.post('/main/another_url',{data:data[0]},function(){
//some code
});
});
jQuery定义了Deferred对象,并重写了ajax代码,使用ajax、get等方法会返回一个Deferred的Promise对象,此对象支持done、fail等方法,并支持链式调用
demo ajax
$.get('/url').done(function(){
//code success
}).fail(function(){
//code fail
});
demo Deferred
var longTimeFunction = function(){
var defe = new $.Deferred();
defe.notify(); //通知,会触发progress
setTimeout(function(){
alert('long time function done!');
if (a){
defe.resolve(); //执行成功,会触发done,可传递参数给done
}
else{
defe.reject();//执行失败,会触发fail,可传递参数
}
},3000);
//此处也可返回defe对象,但暴漏此对象会导致外界调用
//resolve、reject等方法干扰业务正常处理,promise方法返回的
//Promise方法不会暴露这些方法。
return defe.promise();
}
var doneDoing = function(){
//some thing done success
}
longTimeFunction().done(doneDoing).fail(doneFail).progress(function(){
alert("Bing progress,please wait");
});
如果不需要根据执行结果调用不同的方法而是依次调用多个方法,我们可以不使用resolve、reject、notify方法,只调用promise返回promise对象,同时用then执行需要依次执行的方法即可。
demo then
var longWaitFunc = function(){
var defe = new $.Deferred();
//a big array
for(var i in bigArray){
// progress array
}
return defe.promise();
}
$.when(longWaitFunc).then(do1).then(do2).then(do3) ;