2017-09-28 4 views
0

私は複数のajax要求を持つループを持っています。 各Ajaxは常にコールバックによって管理されます。 各ajaxがpromises配列にプッシュされます。最後に$ .whenが常に使用されます。 AJAXが失敗したときにJQuery AJAXの約束はいつも壊れています

$.ajaxが成功した場合は、$.ajaxが成功すると$.when.apply($, promises).always(...); が呼び出されます。

しかし、たとえばが2番目に失敗した場合、$.when.apply($, promises).always(...);は2番目の後にのみ起動され、すべてが3 $.ajaxコールが成功した場合は起動されません。

助けが必要ですか? @ケビン-Bとコード

$(".upload_all").bind("click", function() { 
    var confirmed_count = 0; 
    var error_count = 0; 
    var promises = []; 

    to_uploads.each(function(index,val) { 
    var elem = $(this); 
    var promise = $.ajax({ 
     url: "/upload/storeUploadedFile", 
     type: 'POST', 
    }).always(function(data_or_jqXHR, textStatus, jqXHR_or_errorThrown) { 
     if (textStatus === "success") { 
     // .. 
     } else { 
     // .. 
     }     
    }); 

    promises.push(promise); 
    }); 

    $.when.apply($, promises) 
    .always(function() { 
     console.log("Promises Always! ") // do other stuff 
    }); 
} 
+0

でも、jqueryの約束にもかかわらず?ええ、私はその文脈でそれを使ったことはありません。 jquery 1.6+ –

+2

さて、あなたの$ .when()は、解決するか拒否するかを約束します。約束の1つが拒​​否された場合、すべてが直ちに拒否され、完了していないものはスキップされます。それは、彼らがすべてに到達していなければ、失敗していると約束していることを示唆しています。障害に関係なくすべてを実行するのを待つ場合は、障害を傍受して成功に変換する必要があります。 –

答えて

1

後 は、それに渡された約束のいずれかが拒否された場合$.when戻ります(ほとんどPromise.allと同じ)が拒否されるという約束を言及しています。おそらくこれは、成功していない場合のアップロードをユーザーに知らせることです。

ただし、$.ajax(..).alwayspromise.finallyと同じ)は、「この約束が拒否または解決されたときにこのコールバックを実行する」ことを意味します。あなたはおそらく、すべてのAJAX呼び出しが成功したときに何かをするか、いずれかが失敗したときに何かをしたいと思うでしょう。それにはPromise.all(promises).then(...).catch(...)を使用してください。

$(".upload_all").bind("click", function() { 
    var confirmed_count = 0; 
    var error_count = 0; 

    var promises = to_uploads.map(function(index,val) { // using map instead of each here saves us a couple of steps 
    var elem = $(this); 

    return $.ajax({ 
     url: "/upload/storeUploadedFile", 
     type: 'POST', 
    }) 
     .then(function() { confirmed_count += 1; }) 
     .catch(function() { 
     error_count += 1; 
     return Promise.reject(); // Return a rejected promise to avoid resolving the parent promise 
     }); 
    }); 

    // You can use the native API here which does not require doing the `apply` hack 
    Promise.all(promises) 
    .then(function() { alert('All uploads successful'); }) 
    .catch(function() { alert(`Successful uploads: ${confirmed_count}. Failed uploads: ${error_count}`); } 
} 

jQueryの約束の代替実装を使用しますが、彼らはまだネイティブAPIへの対応を忘れないでください:

  • .then(jQueryの味で.done):成功
  • 上で実行されるコールバックを添付する.catch(JQueryのフレーバーで.fail):エラー時に実行されるコールバックをアタッチします。拒否された約束が返されない限り、これは約束を解決するでしょう。
  • .finally(JQueryのフレーバーでは.always):約束が拒否または解決されたにもかかわらず、他のコールバックの実行後に実行されるコールバックを添付します。
+0

私がコメントした//他のものを実行する 成功のアップロードと失敗したアップロードのサマリーを1つだけ表示するようにしたい。 "この約束が拒否されたか解決されたときにこのコールバックを実行する"という意味ですが、コールバックが発生したときに1つのAjaxが失敗したため、説明しようとしても発生しません。 – Giuseppe

+0

変更を繰り返して、失敗したAPI呼び出しの参照を配列などにプッシュできます。すべてのAJAX呼び出しが成功したとき、または失敗したときに起動するため、 'always'は使用できません。編集を探してください。 – nicooga

関連する問題