参考的阮一峰大大的博客
deffred对象是Jquery1.5以后新增的内容,其用意在于帮助异步或同步事件完成后,方便调用回调函数,所以deferred对象就是jQuery的回调函数解决方案。
Jquery的AJAX返回的结果就是一个deferred对象,先回顾一下通常写AJAX的方式:
$.ajax({
url: "url",
type: "get",
dataType: "json"
success: function(){
console.log("ok");
}
error: function(){
console.log("fail");
}
});
而实际上deferrend对象是允许链式结构的,所以这样规定回调函数是正确的:
$.ajax({
url: "url",
type: "get",
dataType: "json"
}).done(function(){
console.log("ok");
})
.fail(function(){
console.log("fail");
});
// 此时,你可以继续添加done,fail,从而设置多个回调函数
当然,你也可以为多个AJAX指定相同的回调函数,这里用到方法:$.when()
($.when()
中的参数必须是deferrend对象)
$.when($.ajax("url"),$.ajax("url"))
.done(function(){
console.log("ok");
}).fail(function(){
console.log("fail");
})
deffernd对象提供了一套接口,能让所有的操作都能像AJAX一样判断是否执行成功,从而设置对应的回调函数。比如说,我们想要在从后台加载数据完毕(图片,视频加载完成)后进行布局,此时就可以使用这种方式。
var dfd = $.Deferrend();
var longtime = function(longtime(dfd)){
setTimeout(function(){
console.log("执行完毕!");
dfd.resolve();
//这是改变deferred对象状态的函数,resolve()代表了执行成功,对应的done();与之相反的是reject(),对应的false();
},2000)
return dfd; //返回的必须是dfd对象,才能用$.when()方法;
}
$.when(longtime)
.done(function(){
console.log("ok");
}).fail(function(){
console.log("fail");
})
//执行完毕!
// ok
但这种写法是不保险的,因为我们定义的dfd
是全局变量,如果我在上述代码添加一句dfd.resolve();
则会立刻执行console.log("ok")
,2秒后在执行console.log(‘执行完毕!“)
,这是由于延迟函数属于最低优先级,故dfd.resolve();
被先执行,ded的状态一改变便触发回调函数。
为了解决这个问题,Jquery添加了deferrend.promise()方法,它限制了deferrend对象的功能,外部只能提供回调函数,而不能改变其状态。
var dfd = $.Deferrend();
var longtime = function(dfd){
setTimeout(function(){
console.log("执行完毕!");
dfd.reject();
},2000)
return dfd.promise(); //限制dfd的行为
}
$.when(longtime(dfd))
.done(function(){
console.log("ok");
}).fail(function(){
console.log("fail");
});
dfd.resolve();
//执行完毕!
// fail
当然,充当全局变量总是不好的,所以我们可以把dfd置入longtime函数中,成为其局部变量:
var longtime = function(dfd){
var dfd = $.Deferrend();
setTimeout(function(){
console.log("执行完毕!");
dfd.reject();
},2000)
return dfd.promise(); //限制dfd的行为
}
$.when(longtime())
.done(function(){
console.log("ok");
}).fail(function(){
console.log("fail");
});
dfd.resolve();
//执行完毕!
// fail