jquery延迟化失败为成功

发布于 2024-11-14 07:46:08 字数 565 浏览 4 评论 0原文

因此,使用 jQuery deferreds 和 $.when 并行加载许多对象。

$.when(
  a.ajax(), b.ajax(), c.ajax()
).then(
  //do something when all are complete
  complete();
);

现在,b.ajax()有时会失败,但我实际上并不关心。我只想等到所有调用完成后再调用complete()。

不幸的是,一旦b失败,when()就会拒绝,并且永远不会触发then()回调。这是 AFAIK 预期的 $.when() 行为,但是在这种情况下不适合我。

我实际上想要一种方式来表达:

$.when(
  a.ajax(), b.ajax().fail(return success), c.ajax()
).then(...)

或者也许有一种不同的方式来使用 when() ,或更合适的构造?

So in using jQuery deferreds and $.when to load many objects in parallel.

$.when(
  a.ajax(), b.ajax(), c.ajax()
).then(
  //do something when all are complete
  complete();
);

Now, b.ajax() will sometimes fail, but I dont actually care. I just want to wait until all the calls have completed before calling complete().

Unfortunately, as soon as b fails, the when() rejects, and never fires the then()callback. This is AFAIK expected behaviour for $.when(), however dosent suit me in this case.

I effectively want a way to say:

$.when(
  a.ajax(), b.ajax().fail(return success), c.ajax()
).then(...)

Or perhaps there is a different way to use when(), or a more suitable construct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

三月梨花 2024-11-21 07:46:08

如果你想捕获一个promise的失败并将其转换为成功,你可以使用 then 的failFilter返回一个已解决的承诺,如下所示:

deferredCall.then(function(answer) { 
   // this is success. you might transform the answer here.
   return transformed;
}, function() {
   // this is a fail. you might resolve the fail with an empty object.
   return $.Deferred().resolve({}).promise();
});

这样做将确保链可以在失败后继续不间断。

因此,对于您的示例,您可以这样做:

$.when([
   a.ajax(),
   b.ajax().then(function(answer) { 
       return answer; 
   }, function() {
       return $.Deferred().resolve({}).promise();
   }),
   c.ajax()
]).then(function(results) {
    // etc.
});

示例 2:在我的应用程序中,我有时使用 then 来获取关系特定实体的数据,并允许 404 指示不存在这种关系的可能性:

getEntity(id).then(function(entity) {
    return getAssociation(id).then(function(association) {
        entity.association = association;
        return entity;
    }, function() {
        entity.association = null;
        return $.Deferred().resolve(entity).promise();
    });
}).done(function(entity) {
    // etc.
});

注意,较旧的答案建议使用 pipe 方法。从 jQuery 1.8 开始,此方法已被弃用。

If you want to capture the failure of a promise and convert that to a success, you can use the failFilter of then to return a resolved promise, like so:

deferredCall.then(function(answer) { 
   // this is success. you might transform the answer here.
   return transformed;
}, function() {
   // this is a fail. you might resolve the fail with an empty object.
   return $.Deferred().resolve({}).promise();
});

Doing this will ensure that the chain can continue past the failure unbroken.

So, for your example, you might do this:

$.when([
   a.ajax(),
   b.ajax().then(function(answer) { 
       return answer; 
   }, function() {
       return $.Deferred().resolve({}).promise();
   }),
   c.ajax()
]).then(function(results) {
    // etc.
});

Example 2: In my applications, I sometimes use then to get relational data for a particular entity and allow for the possibility of a 404 to indicate that no such relationship exists:

getEntity(id).then(function(entity) {
    return getAssociation(id).then(function(association) {
        entity.association = association;
        return entity;
    }, function() {
        entity.association = null;
        return $.Deferred().resolve(entity).promise();
    });
}).done(function(entity) {
    // etc.
});

Note, older answers suggest using the pipe method. This method is deprecated as of jQuery 1.8.

随心而道 2024-11-21 07:46:08

这比将失败转化为成功更好。

鲜为人知的事实是,如果任何一个参数失败,$.when() 将立即执行 then() 回调。这是设计使然。引用文档:

http://api.jquery.com/jQuery.when/

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

实际上没有内置的方法可以等待所有任务完成,无论它们的成功/失败状态如何。

因此,我为您构建了一个 $.whenAll() :) 它总是等待所有问题都以一种或另一种方式解决:

http://jsfiddle.net/InfinitiesLoop/yQsYK/

Here is something better than hacking a failure into a success.

Little known fact, $.when() will execute the then() callback immediately if any one of the parameters fails. It's by design. To quote the documentation:

http://api.jquery.com/jQuery.when/

In the multiple-Deferreds case where one of the Deferreds is rejected, jQuery.when immediately fires the failCallbacks for its master Deferred. 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.

There's actually no built-in way of waiting until all of them are finished regardless of their success/failure status.

So, I built a $.whenAll() for you :) It always waits until all of them resolve, one way or the other:

http://jsfiddle.net/InfinitiesLoop/yQsYK/

稳稳的幸福 2024-11-21 07:46:08

您可以通过包装 $.Deferred 对象来相当轻松地构建 $.onFailSucceed

$.onCompleteSucceed = function(oldDfd) {
    var newDfd = $.Deferred();

    oldDfd.always(newDfd.resolve);

    return newDfd.promise();
}

然后您可以在此方法中包装适当的调用:

$.when(
  a.ajax(), $.onCompleteSucceed(b.ajax()), c.ajax()
).then(...)

You could build $.onFailSucceed fairly easily by wrapping the $.Deferred object:

$.onCompleteSucceed = function(oldDfd) {
    var newDfd = $.Deferred();

    oldDfd.always(newDfd.resolve);

    return newDfd.promise();
}

You could then wrap the appropriate calls in this method:

$.when(
  a.ajax(), $.onCompleteSucceed(b.ajax()), c.ajax()
).then(...)
七秒鱼° 2024-11-21 07:46:08

所以我最终弄清楚了,请参阅我对其他有相同问题的人的回答:

如何欺骗 jqXHR 总是成功

lonesomeday 的答案很简洁,但不完全是我所追求的。

So i figured it out in the end, see my answer to someone else with the same issue:

how to fool jqXHR to succeed always

lonesomeday's answer was neat, but not quite what i was after.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文