jQuery回调嵌套的解决方案。
其实,jQ已经为我们想好解决方案了,那就是promise模式。下面开始学习。
1、deferred 和promise
首先,一定要明确和区分2个对象,deferred 和promise,不然后面的学习会混乱的。
deferred对象:
创建方法: jQuery.Deferred();
主要方法:resolve , reject , notify ;
done , fail , progress ;
等等,更多请查看api。
简介:一个Deferred(延迟)对象开始于pending状态。 任何回调使用deferred.then(), deferred.always(), deferred.done(), 或者 deferred.fail()添加到这个对象都是排队等待执行。如果使用诸如*deferred.resolve()方法来改变状态,使deferrde的状态改变成 resolved,那么会立刻执行done()方法。
promise对象:
创建方法: Deferred.promise();
主要方法:done,fail,then;
简介: promise 对象其实就是 deferred 对象的特例,因为 promise 对象不能更改异步状态,而 deferred 对象可以。
所以说,promise对象是没有resolve方法的,不能用错了。
2.嵌套改写。
$.ajax({
url : "aaa",
success : ajax2
})
var ajax2 = function() {
$.ajax({
url : "bbb",
success : function(){
alert("执行成功");
})
}
改写之后可以是这样的。
$.ajax("transit.html").then(function() {
return $.ajax("transit.html");
}).fail(function() {
alert("执行失败");
}).done(function() {
alert("执行成功");
})
不管是执行到访问aaa出错,还是访问bbb出错,
都会弹出执行失败,只有都执行成功才会弹出执行成功。
此处 $.ajax(“transit.html”)返回的应该是一个promise对象,因为
没看到有resolve方法。
3.
不得不说的几个方法。
1)、$.when(deferreds )
如果没有参数传递给 jQuery.when(),它会返回一个resolved状态的Promise。
参数可以是0个或多个deferred或者promise对象或者普通的JavaScript对象,
参数是对象。
2.)then (sucessFunc,failFunc)方法,
该方法接受的参数只能是方法,基本作用就是依次执行方法,等待这个方法执行完毕返回一个promise之后才继续执行下一个。又或者是作为回调方法 ,包含成功和失败。
下面举例说明。
网上copy一个例子
var log = function(msg) {
window.console && console.log(msg)
}
function asyncThing1() {
var dfd = $.Deferred();
setTimeout(function() {
log('asyncThing1 seems to be done...');
//dfd.reject('11');
dfd.resolve('111');
}, 1000);
return dfd.promise();
}
function asyncThing2() {
var dfd = $.Deferred();
setTimeout(function() {
log('asyncThing2 seems to be done...');
// dfd.reject('222');
dfd.resolve('222');
}, 1500);
return dfd.promise();
}
function asyncThing3() {
var dfd = $.Deferred();
setTimeout(function() {
log('asyncThing3 seems to be done...');
// dfd.reject('333');
dfd.resolve('333');
}, 1000);
return dfd.promise();
}
/* 每次执行一个.when */
$.when(asyncThing1(), asyncThing2(), asyncThing3()).done(function(res1, res2, res3) {
log('all done!');
log(res1 + ', ' + res2 + ', ' + res3);
});
/*asyncThing1 seems to be done...
asyncThing3 seems to be done...
asyncThing2 seems to be done...
all done!
111, 222, 333
由结果可以看出,$.when()里面的方法基本是通知执行的,执行时机相同的就按照方法的书写顺序来执行。同时执行多个方法,结果就可以同时处理多个。
*/
$.when(asyncThing1()).then(asyncThing2).then(asyncThing3).then(function(res1, res2) {
log('all done!');
log(res1 + ', ' + res2 + ', ');
}, function(rest) {
log("失败了" + rest);
});
/* asyncThing1 seems to be done...
asyncThing2 seems to be done...
asyncThing3 seems to be done...
all done!
333, undefined, */
由结果可以看出
then方法使依次执行的,而且最后的then回调里面也只能获取到
333的信息。