
正文
前端多层回调问题解决方案之$.Deferred
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
javascript引擎是单线程的,但是通过异步回调可以实现IO操作并行执行能力,当业务逻辑复杂的时候我们就进入回调地狱。
本文讲得ajax是在jquery1.5以前的版本,目的旨在让我们理解延迟对象的应用场景,jquery1.5之后,ajax默认就是延迟对象,可以进行链式操作
举例:
a(funtion(){
b(funtion(){
c(funtion(){
d(funtion(){
e(funtion(){
f(funtion(){
g(funtion(){
finish();
});
});
});
});
});
});
});
这还是比较简单的操作,如果每个回调函数还有N多操作,那么更加头疼了。
解决方法:通过jQuery的when().done()实现
1. 函数a,b,c,d,e,f,g都这样写
function a(){
var dtd = $.Deferred();
//这里延迟操作,可能是ajax,也可能是setTimeout
$.post(url,{},function(data){
....
alert("执行完毕!");
dtd.resolve(); // 改变Deferred对象的执行状态
}) ;
return dtd.promise();
}
2. 使用
$.when(
a(),
b(),
c(),
d(),
e(),
f(),
g()
).done(finish).fail() ;
PS: 除了$.when().done()组合,还有一种组合$.when().then()。
done是在when中的延迟对象dtd都resolve的时候才回执行done中的操作,then是延迟对象有一个resolve就执行。类似于“与”和“或”。
如上的例子,如果a函数里面的ajax请求返回的不是我们想要的结果,我们不想让done执行,应该怎么做呢?
function a(){
var dtd = $.Deferred();
//这里延迟操作,可能是ajax,也可能是setTimeout
$.post(url,{},function(data){
if(data == 1){
dtd.resolve(); // 改变Deferred对象的执行状态
}else{
dtd.reject(); // 作用和resolve正好相反
}
});
return dtd.promise();
}
如果a函数服务器返回的是1, 那么done可以执行,如果不是1,那么不会执行done,而是立即执行fail。
如果这里是then那么不会受到影响,只要a,b,c,d,e,f,g有一个resolve。
还有一个函数$when().always(),这个不管when中resolve还是reject,最后都会执行always。
文章转自: http://www.myjscode.com/page/article10.html







