前端多层回调问题解决方案之$.Deferred
Posted 奔跑的蜗牛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端多层回调问题解决方案之$.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
以上是关于前端多层回调问题解决方案之$.Deferred的主要内容,如果未能解决你的问题,请参考以下文章
爬虫日记(100):Twisted:使用Deferred重构回调函数管理