jQuery.ajax 处理继续响应:“成功:”与“.done”?
Posted
技术标签:
【中文标题】jQuery.ajax 处理继续响应:“成功:”与“.done”?【英文标题】:jQuery.ajax handling continue responses: "success:" vs ".done"? 【发布时间】:2012-02-09 01:08:39 【问题描述】:我使用 jQuery 和 AJAX 已经有几个星期了,我看到了两种不同的方式来在调用后“继续”脚本:success:
和 .done
。
从jQuery documentation 的概要中我们得到:
.done():说明:添加解析延迟对象时要调用的处理程序。
success: (.ajax() option): 请求成功时调用的函数。
所以,在 AJAX 调用完成/解决之后,两者都做一些事情。我可以随机使用其中一个吗?有什么区别,什么时候用一个代替另一个?
【问题讨论】:
【参考方案1】:success
一直是 jQuery 中成功回调的传统名称,定义为 ajax 调用中的一个选项。但是,由于实现了$.Deferreds
和更复杂的回调,done
是实现成功回调的首选方式,因为它可以在任何deferred
上调用。
比如成功:
$.ajax(
url: '/',
success: function(data)
);
例如,完成:
$.ajax(url: '/').done(function(data) );
done
的好处在于,$.ajax
的返回值现在是一个延迟承诺,可以绑定到应用程序中的任何其他位置。因此,假设您想从几个不同的地方进行此 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
只是首先调用。
非常好的帖子!顺便说一句,在管道回调中,您不应该使用 jqXHR 参数调用管道函数以检查状态响应吗?例如:.pipe(function(data, textStatus, jqXHR) if (jqXHR.status == 200) ...
@Eder 我使用pipe
解决的场景是请求本身成功但服务器上的脚本没有返回您要查找的内容。您可能不想在服务器端抛出实际的 404 或 500 或其他任何内容,因为您想有意义地区分 http 响应和应用程序响应。在 JSON 中设置响应代码,然后以这种方式使用 pipe
可以让您以更细微的差别处理不同类型的错误。
使用 Promise 的另一个重要好处是您的代码变得更具可读性并且您避免了“回调地狱”。当您有多个回调要在前一个完成后运行每个回调时,尤其如此。使用 Promise,它看起来像 myPromiseCall.then(..).then(..) 而不是与 success 选项一起使用的嵌套复杂的回调结构。【参考方案2】:
如果您在 ajax 中需要 async: false
,则应使用 success
而不是 .done
。否则你最好使用.done
。
这是来自jQuery official site:
从 jQuery 1.8 开始,不推荐使用带有 jqXHR ($.Deferred) 的 async: false;你必须使用success/error/complete回调选项而不是jqXHR对象的相应方法,例如jqXHR.done( )。
【讨论】:
谁提到了async:false
?
$.ajax( url: req_url, ..., async: false, success: function (result, status, req) , error: function (jqXHR, status) );
【参考方案3】:
来自JQuery Documentation
从 jQuery 1.5 开始,$.ajax()
返回的 jqXHR 对象实现了 Promise 接口,为它们提供了 Promise 的所有属性、方法和行为(有关更多信息,请参阅Deferred object)。这些方法采用一个或多个在$.ajax()
请求终止时调用的函数参数。这允许您在单个请求上分配多个回调,甚至在请求完成后分配回调。 (如果请求已经完成,则立即触发回调。) jqXHR 对象的可用 Promise 方法包括:
jqXHR.done(function( data, textStatus, jqXHR ) );
成功回调选项的替代构造,请参阅deferred.done()
了解实现细节。
jqXHR.fail(function( jqXHR, textStatus, errorThrown ) );
错误回调选项的替代构造,.fail()
方法替换了已弃用的 .error() 方法。实现细节参考 deferred.fail()。
jqXHR.always(function( data|jqXHR, textStatus, jqXHR|errorThrown ) );
(在 jQuery 1.6 中添加)
完整回调选项的替代构造,.always()
方法替换了已弃用的 .complete()
方法。
响应成功的请求,该函数的参数与.done()
的参数相同:data、textStatus和jqXHR对象。对于失败的请求,参数与.fail()
的参数相同:jqXHR 对象、textStatus 和errorThrown。实现细节参考deferred.always()
。
jqXHR.then(function( data, textStatus, jqXHR ) , function( jqXHR, textStatus, errorThrown ) );
结合了.done()
和.fail()
方法的功能,允许(从jQuery 1.8 开始)底层的Promise 被操纵。实现细节参考deferred.then()
。
弃用通知: 自 jQuery 3.0 起,
jqXHR.success()
、jqXHR.error()
和jqXHR.complete()
回调已被删除。您可以使用jqXHR.done()
、jqXHR.fail()
和jqXHR.always()
。
【讨论】:
以上是关于jQuery.ajax 处理继续响应:“成功:”与“.done”?的主要内容,如果未能解决你的问题,请参考以下文章
从图像响应中设置 jQuery ajax 成功中的 div 背景
本地加载 XML 的 jQuery Ajax 问题 - Safari 版本 11.0 - 错误:XMLHttpRequest 无法加载 .xml。预检响应不成功
jQuery AJAX 轮询 JSON 响应,基于 AJAX 结果或 JSON 内容进行处理