jQuery何时/ then / fail并发ajax请求:哪个请求失败?

时间:2011-04-26 18:45:04

标签: javascript jquery jquery-deferred

想象一下我们想要在'foo'和'bar'的并发请求成功完成后执行某些操作的情况,或者如果其中一个或两个都失败则报告错误:

$.when($.getJSON('foo'), $.getJSON('bar'))
  .then(function(foo, bar) {
    console.log( 'I fire if BOTH requests are successful!' );
  })
  .fail(function() {
    console.log( 'I fire if one or more requests failed.' );
  });

如何确定1)'foo'请求失败,或2)'bar'请求失败,或3)如果两者都失败了?

3 个答案:

答案 0 :(得分:10)

只需向$.getJSON返回的每个承诺添加失败调用:

function make_error_handler(msg) {
    return function() { console.log(msg); };
}

$.when($.getJSON('foo').fail(make_error_handler("foo failed"))
            , $.getJSON('bar').fail(make_error_handler("bar failed")))
  .then(function(foo, bar) {
    console.log( 'I fire if BOTH requests are successful!' );
  })
  .fail(function() {
    console.log( 'I fire if one or more requests failed.' );
  });

如果您需要更细粒度的控制,可以重载$.getJSON以将其他信息返回到失败函数 - 请参阅deferred.rejectWith上的jQuery文档

答案 1 :(得分:1)

来自the documentation on jQuery.when

  

在多个Deferreds案例中,其中一个Deferreds被拒绝,jQuery.when立即触发其主Deferred的failCallbacks。请注意,此时某些延迟可能仍未解决。如果您需要为此情况执行其他处理,例如取消任何未完成的ajax请求,则可以在闭包中保留对基础jqXHR对象的引用,并在failCallback中检查/取消它们。

换句话说,如果需要,您应该保留对每个请求的引用,并自己手动检查。

难点在于,当调用失败回调时,任何数量的延迟可以仍然是未完成的,因此在该状态下它们既没有失败也没有成功。

我希望文档说明在这种情况下确切地传递给失败处理程序的内容。从源代码来看,似乎失败处理程序收到的参数取决于Deferred首先失败:

args[ i ].promise().then( resolveFunc(i), deferred.reject );

我不是jQuery内部的专家,但我认为这只是让你的每一个Deferred都调用“master”Deferred的reject方法,它通常会传递给它的处理程序。不理想,如果你问我......但是我可能误读了这个。

我想知道他们是否意味着这个:

args[ i ].promise().then( resolveFunc(i), func() { deferred.reject(args); } );

答案 2 :(得分:0)

您可以致电.isResolved()来检查请求是否确实完成,但.when()的问题是,只要 请求失败,它就会失败,所以您无法可靠地判断其他请求是否可能即将失败。

我相信the answer I just posted similar question将通过为每个AJAX查询创建一个额外的$.Deferred来解决(没有双关语意)此要求,这样您就可以等到知道两个AJAX调用的实际结果。