jQuery之Deferred对象详解(4)
$.when()接受多个deferred对象作为参数,当它们全部运行成功后,才调用resolved状态的回调函数,但只要其中有一个失败,就调用rejected状态的回调函数。它相当于将多个非同步操作,合并成一个。
$.when(
$.ajax( "/main.php" ),
$.ajax( "/modules.php" ),
$.ajax( "/lists.php" )
).then(successFunc, failureFunc);
上面代码表示,要等到三个ajax操作都结束以后,才执行then方法指定的回调函数。
when方法里面要执行多少个操作,回调函数就有多少个参数,对应前面每一个操作的返回结果。
$.when(
$.ajax( "/main.php" ),
$.ajax( "/modules.php" ),
$.ajax( "/lists.php" )
).then(function (resp1, resp2, resp3){
console.log(resp1);
console.log(resp2);
console.log(resp3);
});
上面代码的回调函数有三个参数,resp1、resp2和resp3,依次对应前面三个ajax操作的返回结果。
when方法的另一个作用是,如果它的参数返回的不是一个Deferred或Promise对象,那么when方法的回调函数将 立即运行。
$.when({testing: 123}).done(function (x){
console.log(x.testing); // "123"
});
上面代码中指定的回调函数,将在when方法后面立即运行。
利用这个特点,我们可以写一个具有缓存效果的异步操作函数。也就是说,第一次调用这个函数的时候,将执行异步操作,后面再调用这个函数,将会返回缓存的结果。
function maybeAsync( num ) {
var dfd = $.Deferred();
if ( num === 1 ) {
setTimeout(function() {
dfd.resolve( num );
}, 100);
return dfd.promise();
}
return num;
}
$.when(maybeAsync(1)).then(function (resp){
$('#target').append('<p>' + resp + '</p>');
});
$.when(maybeAsync(0)).then(function (resp){
$('#target').append( '<p>' + resp + '</p>');
});
上面代码表示,如果maybeAsync函数的参数为1,则执行异步操作,否则立即返回缓存的结果。
实例
wait方法
我们可以用deferred对象写一个wait方法,表示等待多少毫秒后再执行。
$.wait = function(time) {
return $.Deferred(function(dfd) {
setTimeout(dfd.resolve, time);
});
}
使用方法如下:
$.wait(5000).then(function() {
alert("Hello from the future!");
});
改写setTimeout方法
在上面的wait方法的基础上,还可以改写setTimeout方法,让其返回一个deferred对象。
function doSomethingLater(fn, time) {
var dfd = $.Deferred();
setTimeout(function() {
dfd.resolve(fn());
}, time || 0);
return dfd.promise();
}
var promise = doSomethingLater(function (){
console.log( '已经延迟执行' );
}, 100);
自定义操作使用deferred接口