jQuery.ajax处理继续响应:“成功:”还是“ .done”?


309

我已经使用jQuery和AJAX几周了,并且在调用完成后,我看到了两种“继续”脚本的不同方式:success:.done

jQuery文档的提要中,我们得到:

.done():说明:添加要解析Deferred对象时要调用的处理程序。

成功:(。ajax()选项):如果请求成功,则要调用的函数。

因此,在AJAX调用完成/解决之后,两者都要做一些事情。我可以随机使用其中之一吗?有什么区别?何时使用一种替代另一种?

Answers:


469

success一直是jQuery中成功回调的传统名称,定义为ajax调用中的一个选项。但是,由于实现了$.Deferreds更复杂的回调,因此done是实现成功回调的首选方法,因为可以在any上调用它deferred

例如,成功:

$.ajax({
  url: '/',
  success: function(data) {}
});

例如,完成:

$.ajax({url: '/'}).done(function(data) {});

令人高兴的done是,$.ajax现在的返回值是一个可以与应用程序中其他任何地方绑定的递延承诺。假设您要在几个不同的地方进行此ajax调用。而不是你的成功传递函数作为一个选项,以使这个Ajax调用的功能,你可以有函数返回$.ajax本身并绑定你的回调donefailthen,或什么的。请注意,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定义(请确保返回一个promise或至少一个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以完全相同的方式使用。


2
我不知道success:/ 的相互作用如何.done()定义(如果有的话)。例如success:.done()这几天刚开始实施?

6
您的意思是如果同时拥有success:.done正在接受ajax通话?好问题。由于所有其他回调均按照绑定的顺序被调用,因此我的猜测是肯定的,success它仅被首先调用。
glortho 2012年

1
很好的帖子!顺便说一句,在管道回调中,您是否不应该使用jqXHR参数调用管道功能来检查状态响应?例如:.pipe(功能(数据,textStatus,jqXHR){如果(jqXHR.status == 200){...
埃德尔

@Eder我正在解决的这种情况pipe是一种请求本身成功但服务器上的脚本未返回您正在寻找的情况。您可能不希望在服务器端抛出实际的404或500或其他值,因为您想有意义地区分http响应和应用程序响应。在JSON中设置响应代码,然后使用pipe这种方式,可以让您更加细致地处理各种错误。
glortho

使用Promise的另一个重要好处是您的代码变得更具可读性,并且避免了“回调地狱”。当您有多个回调要在上一个完成后运行每个回调时,尤其如此。有了promise,它将看起来像myPromiseCall.then(..)。then(..),而不是与成功选项一起使用的嵌套的回调复杂结构。
BornToCode

5

如果需要async: false使用ajax,则应使用success代替.done。否则您最好使用.done。这是从jQuery官方网站

从jQuery 1.8开始,不建议使用async:false和jqXHR($ .Deferred);您必须使用成功/错误/完成回调选项,而不要使用jqXHR对象的相应方法,例如jqXHR.done()


谁提async:false
利亚姆

$.ajax({ url: req_url, ..., async: false, success: function (result, status, req) { }, error: function (jqXHR, status) { } });
AmirHossein Manian

0

JQuery文档

$.ajax()jQuery 1.5开始返回的jqXHR对象实现Promise接口,为它们提供Promise的所有属性,方法和行为(有关更多信息,请参见Deferred对象)。这些方法采用一个或多个在$.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进行操作。.then()有关实现的详细信息,请参阅延迟。

弃用注意:所述的jqXHR.success()jqXHR.error()jqXHR.complete()回调除去的jQuery 3.0。您可以使用 jqXHR.done()jqXHR.fail()jqXHR.always()来代替。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.