jquery推迟转为成功

时间:2011-06-06 23:49:54

标签: jquery jquery-deferred promise

因此,在使用jQuery延迟和$.when并行加载许多对象时。

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

现在,b.ajax()有时会失败,但我真的不在乎。我只想等到所有调用完成后再调用complete()。

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

我实际上想要一种说法:

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

或许有一种不同的方式可以使用when()或更合适的构造?

4 个答案:

答案 0 :(得分:6)

如果要捕获promise的失败并将其转换为成功,可以使用then的failFilter返回已解析的promise,如下所示:

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开始,不推荐使用此方法。

答案 1 :(得分:3)

这不仅仅是将失败变成成功的事情。

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

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

  

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

实际上没有内置的等待方式,直到所有这些方式都完成,无论其成功/失败状态如何。

所以,我为你建了一个$ .whenAll():)它总是等到所有这些都以某种方式解决:

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

答案 2 :(得分:1)

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

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

    oldDfd.always(newDfd.resolve);

    return newDfd.promise();
}

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

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

答案 3 :(得分:1)

所以我最终弄明白了,看看我对同一个问题的答案:

how to fool jqXHR to succeed always

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

相关问题