8

したがって、jQueryの延期を使用し、$.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()、またはより適切な構成がありますか?

4

4 に答える 4

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:私のアプリケーションでは、特定のエンティティのリレーショナルデータを取得し、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.
});

古い回答では、パイプ方式を使用することを提案していることに注意してください。このメソッドは、jQuery1.8で非推奨になりました。

于 2015-05-13T16:00:38.590 に答える
3

これは、失敗を成功に導くよりも優れたものです。

あまり知られていない事実ですが、パラメータのいずれかが失敗した場合、$。when()はthen()コールバックをすぐに実行します。これは仕様によるものです。ドキュメントを引用するには:

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

Deferredの1つが拒​​否された複数のDeferredの場合、jQuery.whenはマスターDeferredのfailCallbacksをすぐに起動します。一部の延期は、その時点でまだ解決されていない可能性があることに注意してください。この場合、未完了のajaxリクエストをキャンセルするなど、追加の処理を実行する必要がある場合は、基になるjqXHRオブジェクトへの参照をクロージャに保持し、failCallbackでそれらを検査/キャンセルできます。

実際には、成功/失敗のステータスに関係なく、すべてが終了するまで待つ組み込みの方法はありません。

だから、私はあなたのために$ .whenAll()を作成しました:)それは、いずれかの方法で、それらすべてが解決するまで常に待機します:

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

于 2011-10-24T20:38:25.593 に答える
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(...)
于 2011-06-07T07:47:43.423 に答える
1

だから私は最終的にそれを理解しました、同じ問題を抱えている他の誰かへの私の答えを見てください:

常に成功するためにjqXHRをだます方法

寂しい日の答えはきちんとしていましたが、私が求めていたものとはまったく異なりました。

于 2011-06-28T13:20:29.037 に答える