jQueryの「each()」関数は同期ですか?


131

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

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()関数が非同期で実行されるようです。私は正しいですか?なぜこれが機能しないのですか?


2
検証コードはどのように見えますか?each同期ですが、中のコードはそうではないかもしれません...
lonesomeday

1
eachそれ自体は同期的に処理されます。ループ内から独自の非同期操作を開始していますか?
Jon

3
ここで同様の問題..どのようにそれを解決しましたか?
sakthig

ずいぶん前のことですが、思い出せません。しかし、私は答えが私を助けたことを知っています。そのため、検証コードで非同期コードブロックを使用した可能性があります(ajaxリクエストを使用してアドレスを検証するなど)。
Saeed Neamati

1
hmm ..iこの方法で解決しました..機能していなかった各関数内で「return false」を実行していたと思います..現在、この各関数内にフラグを維持し、検証の最後にそのフラグを返しています..
sakthig

回答:


158

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


7

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

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


7
約束もあります...ただ言うだけです:)

6

この質問をするもう1つの理由は、(。each())関数がfalseを返したときに.eachが反復を単に停止し、追加の変数を使用して「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');
}

2

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

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
});

2

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


1

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

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

それが私のやり方

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

0

同じ問題がありました。私の$ .eachはajax呼び出しの成功関数の中にありました。私は追加することで私のajax呼び出しを同期させましたasync: false、そしてそれはうまくいきました。


-9

jQuery.eachメソッドは同期的にループしますが、特定の順序で項目をループすることは保証できません。


21
いいえ、ドキュメントに表示される順序で常にループします。
アブラハム

3
それはあなたが何を繰り返しているかに依存します。それぞれが配列でのインデックス順序の実行を保証しますが、オブジェクトについては保証しません(これは明らかです)。
Deadron 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.