简体   繁体   English

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

[英]jQuery when/then/fail with concurrent ajax requests: Which request failed?

Imagine a scenario where we want to do something after the concurrent requests for 'foo' and 'bar' have completed successfully, or report an error if one or both of them fails: 想象一下我们想要在'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.' );
  });

How can I determine if 1) the request for 'foo' failed, or 2) the request for 'bar' failed, or 3) if both failed? 如何确定1)'foo'请求失败,或者2)'bar'请求失败,或3)如果两者都失败了?

Simply add a fail call to each promise that is returned from $.getJSON : 只需为$.getJSON返回的每个promise添加一个失败调用:

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.' );
  });

If you need more fine-grained control you can overload $.getJSON to return additional information to the fail function -- see jQuery's documentation on deferred.rejectWith 如果你需要更细粒度的控制,你可以重载$.getJSON来向失败函数返回其他信息 - 请参阅关于deferred.rejectWith jQuery文档

From the documentation on jQuery.when jQuery.when上的文档

In the multiple-Deferreds case where one of the Deferreds is rejected, jQuery.when immediately fires the failCallbacks for its master Deferred. 在多个Deferreds案例中,其中一个Deferreds被拒绝,jQuery.when会立即触发其主Deferred的failCallbacks。 Note that some of the Deferreds may still be unresolved at that point. 请注意,此时某些延迟可能仍未解决。 If you need to perform additional processing for this case, such as canceling any unfinished ajax requests, you can keep references to the underlying jqXHR objects in a closure and inspect/cancel them in the failCallback. 如果需要对此情况执行其他处理,例如取消任何未完成的ajax请求,则可以在闭包中保留对基础jqXHR对象的引用,并在failCallback中检查/取消它们。

In other words, you are supposed to keep the references to each request, and check it manually yourself, if you need to. 换句话说,您应该保留对每个请求的引用,并在需要时自己手动检查。

The difficulty is that when the fail callback is called, any number of deferred's can still be outstanding , thus at that state they have neither failed nor succeeded. 困难在于,当调用失败回调时,任何数量的延迟仍然可以是未完成的 ,因此在该状态下它们既没有失败也没有成功。

I wish the documentation explained a bit better as to exactly what is passed to the fail handler in this case. 我希望文档更好地解释在这种情况下确切传递给失败处理程序的内容。 Judging from the source code though, it seems that the arguments received by the fail handlers depend on which Deferred fails first: 从源代码来看,似乎失败处理程序收到的参数取决于Deferred首先失败:

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

I'm no expert on jQuery internals, but I think this simply lets each of your Deferred's call the "master" Deferred's reject method with whatever arguments it would normally pass to its handlers. 我不是jQuery内部的专家,但我认为这只是让你的每个Deferred调用“master”Deferred的reject方法,它通常会传递给它的处理程序。 Not ideal, if you ask me... but then I could be misreading this. 不理想,如果你问我......但是我可能会误读这个。

I do wonder if they meant this though: 我不知道他们是否意味着这个:

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

You could call .isResolved() to check whether a request did actually complete, but the problem with .when() is that it'll fail as soon as either request fails, so you can't reliably tell whether the other request might be about to fail. 你可以调用.isResolved()来检查请求是否确实真正完成,但这个问题.when()是作为要么请求失败,它会立即失效,所以你不能可靠地告诉其他请求是否可能即将失败。

I believe the answer I just posted to a similar question will resolve (no pun intended) this requirement, by creating an extra $.Deferred for each AJAX query, which allows you to wait until you know the actual outcome of both AJAX calls. 我相信我刚刚发布类似问题 的答案将通过为每个AJAX查询创建一个额外的$.Deferred来解决(没有双关语)这个要求,这允许你等到你知道两个AJAX调用的实际结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM