我已经使用jQuery和AJAX几周了,我看到两种不同的方法在调用完成后"继续"脚本:success:和.done。
从jQuery文档的概要我们得到:
.done(): Description: Add handlers to be called when the Deferred object is resolved.
success: (.ajax() option): A function to be called if the request succeeds.
因此,在AJAX调用完成/解决之后,两者都做了一些事情。 我可以随机使用其中一个吗? 有什么区别,什么时候使用而不是另一个?
success一直是jQuery成功回调的传统名称,定义为ajax调用中的一个选项。但是,由于$.Deferreds和更复杂的回调的实现,done是实现成功回调的首选方法,因为它可以在任何deferred上调用。
例如,成功:
$.ajax({
url: '/',
success: function(data) {}
});
例如,完成:
$.ajax({url: '/'}).done(function(data) {});
关于done的好处是$.ajax的返回值现在是一个延迟的promise,可以绑定到应用程序中的任何其他位置。所以,假设你想从几个不同的地方进行这个ajax调用。而不是将成功函数作为执行此ajax调用的函数的选项传递,您可以让函数返回$.ajax本身并使用done,fail,then或其他任何内容绑定回调。请注意,always是一个回调,无论请求成功还是失败,它都将运行。 done仅在成功时触发。
例如:
function xhr_get(url) {
return $.ajax({
url: url,
type: 'get',
dataType: 'json',
beforeSend: showLoadingImgFn
})
.always(function() {
// remove loading image maybe
})
.fail(function() {
// handle request failures
});
}
xhr_get('/index').done(function(data) {
// do stuff with index data
});
xhr_get('/id').done(function(data) {
// do stuff with id data
});
在可维护性方面,这一点的一个重要好处是,您已将ajax机制包装在特定于应用程序的函数中。如果你决定将来需要$.ajax调用以不同的方式运行,或者你使用不同的ajax方法,或者你不再使用jQuery,你只需要更改xhr_get定义(确保返回一个承诺或至少一种done方法,在上述例子的情况下)。整个应用程序中的所有其他引用可以保持不变。
使用$.Deferred可以做更多(更酷)的事情,其中??一个是使用pipe来触发服务器报告的错误,即使$.ajax请求本身成功。例如:
function xhr_get(url) {
return $.ajax({
url: url,
type: 'get',
dataType: 'json'
})
.pipe(function(data) {
return data.responseCode != 200 ?
$.Deferred().reject( data ) :
data;
})
.fail(function(data) {
if ( data.responseCode )
console.log( data.responseCode );
});
}
xhr_get('/index').done(function(data) {
// will not run if json returned from ajax has responseCode other than 200
});
在此处阅读有关$.Deferred的更多信息:http://api.jquery.com/category/deferred-object/
注意:从jQuery 1.8开始,pipe已被弃用,支持以完全相同的方式使用then。
我想知道如何定义success: / .done()的交互。例如。是success:这些天刚刚实现为第一个.done()?
你的意思是如果你在ajax调用上同时拥有success:和.done?好问题。由于所有其他回调都是按照它们绑定的顺序调用的,我的猜测是肯定的,首先调用success。
是的,确实会出现这种情况:jsfiddle.net/9L7dD
非常好的帖子!在管道回调中,你不应该用jqXHR参数调用管道函数来检查状态响应吗?例如:.pipe(函数(data,textStatus,jqXHR){if(jqXHR.status == 200){...
@Eder我使用pipe解决的方案是请求本身成功但服务器上的脚本没有返回您要查找的内容。您可能不想在服务器端抛出实际的404或500或其他任何内容,因为您希望有意义地区分http响应和应用程序响应。在JSON中设置响应代码然后使用pipe这种方式可以让您处理不同类型的错误,并带来更多细微差别。
使用promises的另一个重要好处是你的代码变得更易读,你可以避免"回调地狱"。当您有多个回调要在上一个完成后运行每个回调时,这通常是正确的。使用promises,它看起来像myPromiseCall.then(..)。then(..)而不是与success选项一起使用的嵌套复杂的回调结构。
如果在ajax中需要async: false,则应使用success而不是.done。否则你最好使用.done。
这是来自jQuery官方网站:
As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated; you must use the success/error/complete callback options instead of the corresponding methods of the jqXHR object such as jqXHR.done().
谁提到async:false?
$.ajax({ url: req_url, ..., async: false, success: function (result, status, req) { }, error: function (jqXHR, status) { } });