转载地址不详,总之来自网络
Deferred 对象解决 JS 异步编程,实现 Common Promise/A 规范。deferred 对象是 jQuery 回调函数的解决方案。
传统写法
$.ajax({
url : "test.html",
success : function() {
alert("哈哈,成功了!");
},
error : function() {
alert("出错啦!");
}
});
新的写法
$.ajax("test.html").done(function() {
alert("哈哈,成功了!");
}).fail(function() {
alert("出错啦!");
});
好处1:多个回调
$.ajax("test.html").done(function() {
alert("哈哈,成功了!");
}).fail(function() {
alert("出错啦!");
}).done(function() {
alert("第二个回调函数!");
});
好处2:多个操作都成功
# 两个操作:$.ajax("test1.html") 和 $.ajax("test2.html"),都成功则调用 done,否则调用 fail
$.when($.ajax("test1.html"), $.ajax("test2.html")).done(function() {
alert("哈哈,成功了!");
}).fail(function() {
alert("出错啦!");
});
$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
.then(myFunc, myFailure);
普通函数也可以使用 deferred 对象
并没有返回 deferred 对象,而是返回 promise() 对象,好处是不能在外部改变 deferred 的状态,即:调用 resolve 或 reject
$.when() 的参数必须是 deferred 对象
deferred 对象最大优点:把这一套回调函数接口,从 ajax 操作扩展到所有操作
deferred 对象三种执行状态
* 未完成
* 已完成
* 已失败
- 如果执行状态是已完成(resolved),deferred 对象立刻调用 done() 方法指定的回调函数
- 如果执行状态是已失败,调用 fail() 方法指定的回调函数
- 如果执行状态是未完成,则继续等待,或调用 progress() 方法指定的回调函数,jQuery1.7 添加
ajax 操作,deferred 对象根据返回结果,自动改变自身的执行状态
在普通函数 wait() 中,执行状态必须由程序员手动指定
* dtd.resolve(),将 dtd 对象的执行状态从未完成改为已完成,触发 done() 方法
* dtd.reject(),将 dtd 对象的执行状态从未完成改为已失败,触发 fail() 方法
var wait = function() {
// 函数内部新建 Deferred 对象
var dtd = $.Deferred();
var tasks = function() {
alert("执行完毕!");
// 改变 Deferred 对象的执行状态
dtd.resolve();
};
setTimeout(tasks, 5000);
// 返回 promise 对象
return dtd.promise();
};
$.when(wait()).done(function() {
alert("哈哈,成功了!");
}).fail(function() {
alert("出错啦!");
});
- $.Deferred() 生成一个 deferred 对象
- deferred.done() 指定操作成功时的回调函数
- deferred.fail() 指定操作失败时的回调函数
- deferred.promise() 没有参数时,返回一个新 deferred 对象,该对象运行状态无法改变;接受参数时,作用为在参数对象上部署 deferred 接口
- deferred.resolve() 手动改变 deferred 对象的运行状态为”已完成”,从而立即触发 done() 方法
- deferred.reject() 与 deferred.resolve() 正好相反,调用后将 deferred 对象运行状态变为”已失败”,从而立即触发 fail() 方法
- $.when() 为多个操作指定回调函数
deferred.then()
# 有时为省事,可把 done() 和 fail() 合在一起写,就是 then() 方法
$.when($.ajax( "/main.php" )).then(successFunc, failureFunc);
deferred.always()
# 指定回调函数,不管调用 deferred.resolve() 还是 deferred.reject(),最后总执行
$.ajax( "test.html" ).always( function() { alert("已执行!");} );
done/resolve
function cb() {
alert('success')
}
var deferred = $.Deferred()
deferred.done(cb)
setTimeout(function() {
deferred.resolve()
}, 3000)
fail/reject
function cb() {
alert('fail')
}
var deferred = $.Deferred()
deferred.fail(cb)
setTimeout(function() {
deferred.reject()
}, 3000)
progress/notify
function cb() {
alert('progress')
}
var deferred = $.Deferred()
deferred.progress(cb)
setInterval(function() {
deferred.notify()
}, 2000)
不断调用,如:进度条更新进度值
串
function fn1() {
alert('success')
}
function fn2() {
alert('fail')
}
function fn3() {
alert('progress')
}
var deferred = $.Deferred()
// 烤串
deferred.done(fn1).fail(fn2).progress(fn3) // 链式操作
setTimeout(function() {
deferred.resolve()
//deferred.reject()
//deferred.notify()
}, 3000)
串2
function fn1() {
alert('success')
}
function fn2() {
alert('fail')
}
function fn3() {
alert('progress')
}
var deferred = $.Deferred()
// Common Promise/A 的实现
deferred.then(fn1, fn2, fn3)
不管成功,失败,总是 always
var deferred = $.Deferred()
deferred.always(function() {
var state = deferred.state()
if ( state === 'resolved') {
alert('success')
} else if (state === 'rejected') {
alert('fail')
}
})
setTimeout(function() {
deferred.resolve()
//deferred.reject()
}, 3000)
全部成功才
function fn1() {
alert('done1')
}
function fn2() {
alert('done2')
}
function fn3() {
alert('all done')
}
var deferred1 = $.Deferred()
var deferred2 = $.Deferred()
deferred1.done(fn1)
deferred2.done(fn2)
$.when(deferred1, deferred2).done(fn3)
setTimeout(function() {
deferred1.resolve()
deferred2.resolve()
}, 3000)
先后弹出 done1、done2、all done。有一个 reject,fn3 不被执行
deferred.promise() 返回只能添加回调的对象,对象与 $.Deferred() 返回对象不同,只能 done/fail/progress,不能 resolve/reject/notify。
即只能 callbacks.add,没 callbacks.fire,是正统 Deferred 对象的阉割版。