web-dev-qa-db-ja.com

jQueryの「each()」関数は同期していますか?

検証のためにこのシナリオを検討してください。

function validateForm (validCallback) {
   $('#first-name').add($('#last-name')).add($('#address')).each(function () {
      // validating fields and adding 'invalid' class to invalid fields.
   });
   // doing validation this way for almost 50 fields (loop over 50 fields)
   if ($('#holder .invalid').length == 0) {
       // submitting data here, only when all fields are validated.
   }
}

さて、私の問題は、ループが終了する前にifブロックが実行されることです。 validateFormの本体は同期的に実行されると予想していましたが、jQuery each()関数は非同期に実行されるようです。私は正しいですか?なぜこれが機能しないのですか?

124
Saeed Neamati

はい、jQuery eachメソッドは同期的です。ほとんどすべてのJavaScriptは同期的です。唯一の例外は、AJAX、タイマー(setTimeoutおよびsetInterval)、およびHTML5 Web Workersです。
あなたの問題はおそらくあなたのコードのどこかにあるでしょう。

149
Abraham

jQueryは、純粋にJavaScriptライブラリです。 ajaxsetTimeout、およびsetIntervalを除き、JavaScriptで非同期に実行できるものはありません。したがって、eachは間違いなく同期的に実行されます。 eachブロックコード内には間違いなくjsエラーがあります。コンソールでエラーを確認する必要があります。

または、jQuery queue を見て、キュー内の任意の関数を実行できます。これにより、前のコードの実行が完了したときにのみキュー関数が実行されるようになります。

7
ShankarSangoli

その質問をするもう1つの理由は、.eachが(.each())関数がfalseを返したときに繰り返しを停止し、「return false」情報を渡すために追加の変数を使用する必要があることです。

var all_ok=true;
$(selector).each(function(){
    if(!validate($(this))){
        all_ok=false; //this tells the outside world something went wrong
        return false; //this breaks the .each iterations, returning early
    }
});
if(!all_ok){
    alert('something went wrong');
}
4
Morg.

それが私がそれをする方法

 function getAllEventsIndexFromId(id) {
    var a;
    $.each(allEvents, function(i, val) {
        if (val.id == id) { a=i; }
    });
    return a;
 }
1
Miguel

.each()関数のreturn falseはループのみを中断し、ループ外の残りのコードは引き続き実行されます。したがって、.each()ループにフラグを設定し、ループ外でチェックしてください。

1
M Hussain

私にとっては非同期のように動作します。同期が機能する場合、なぜそのように機能するのか:

var newArray = [];
$.each( oldArray, function (index, value){
        if($.inArray(value["field"], field) === -1){
            newArray.Push(value["field"]);
        }
    }
);

//do something with newArray here doesn't work, newArray is not full yet

$.when.apply($, newArray).then(function() {
    //do something with newArray works!! here is full
});
1
Tuitx

同じ問題。だから私はこのように修正します

var y = jQuery(this).find(".extra_fields");
for(var j in y)
{
    if( typeof  y[j] =='object')
    {
        var check = parseInt(jQuery(y[j]).val());
        if(check==0){
            jQuery(y[j]).addClass('js_warning');
            mes="Bạn vui lòng chọn đầy đủ các thuộc tính cho sản phẩm";
            done=false;
            eDialog.alert(mes);
            return false;
        }
    }

}
1
user3027521

同じ問題がありました。私の$ .eachはajax呼び出しの成功関数内にありました。 async: falseを追加してajax呼び出しを同期しましたが、動作しました。

0