Apakah fungsi jQuery "each ()" sinkron?

131

pertimbangkan skenario ini untuk memvalidasi:

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.
   }
}

Sekarang, masalah saya adalah, jika blok dijalankan sebelum loop selesai. Saya berharap tubuh validateFormdieksekusi secara sinkron, tetapi tampaknya each()fungsi jQuery dijalankan secara tidak sinkron. Apakah saya benar? Kenapa ini tidak berhasil?

Saeed Neamati
sumber
2
Seperti apa bentuk kode validasi? eachsinkron, tetapi kode di dalamnya mungkin tidak ...
lonesomeday
1
eachitu sendiri diproses secara serempak. Apakah Anda memulai operasi async Anda sendiri dari dalam loop?
Jon
3
masalah serupa di sini .. bagaimana Anda menyelesaikannya?
sakthig
Sudah lama sekali, saya tidak ingat. Tetapi saya tahu bahwa jawabannya membantu saya. Jadi, saya mungkin telah menggunakan blok kode async dalam kode validasi saya (seperti mencoba memvalidasi alamat menggunakan permintaan ajax).
Saeed Neamati
1
hmm .. saya menyelesaikannya dengan cara ini .. saya melakukan "return false" di dalam setiap fungsi yang tidak berfungsi saya kira .. sekarang saya memelihara bendera di dalam setiap fungsi ini dan mengembalikan bendera itu di akhir validasi ..
sakthig

Jawaban:

158

Ya, eachmetode jQuery sinkron. Hampir SEMUA JavaScript bersinkronisasi. Satu-satunya pengecualian adalah AJAX, timer ( setTimeoutdan setInterval), dan Pekerja Web HTML5.
Masalah Anda mungkin ada di tempat lain dalam kode Anda.

Abraham
sumber
7

jQueryadalah murni perpustakaan javascript. Kecuali ajax, setTimeoutdan setIntervaltidak ada yang dapat dijalankan secara asinkron JavaScript. Jadi eachpasti dijalankan secara serempak. Pasti ada beberapa kesalahan js di dalam eachkode blok. Anda harus melihat di konsol untuk setiap kesalahan.

Atau Anda dapat melihat antrian jQuery untuk menjalankan fungsi apa pun dalam antrian. Ini akan memastikan fungsi yang antri akan dieksekusi hanya ketika eksekusi kode sebelumnya selesai.

ShankarSangoli
sumber
7
ada juga janji ... hanya mengatakan :)
6

Alasan lain untuk mengajukan pertanyaan itu adalah .each hanya akan menghentikan iterasi ketika fungsi (.each ()) mengembalikan false, dan variabel tambahan harus digunakan untuk meneruskan informasi "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');
}
Morg.
sumber
2

Bagi saya itu berfungsi seperti asinkron. Jika berhasil disinkronkan, mengapa itu berfungsi seperti itu:

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
});
Tuitx
sumber
2

return falsedalam .each()fungsi istirahat hanya loop, dan kode yang tersisa di luar loop masih dijalankan. Jadi atur flag dalam .each()lingkaran dan periksa di luar loop.

M. Hussain
sumber
1

Permasalahan yang sama. Jadi saya perbaiki seperti ini

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

}
pengguna3027521
sumber
1

Begitulah cara saya melakukannya

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

Saya memiliki masalah yang sama. $ .each saya ada di dalam fungsi keberhasilan panggilan ajax. saya membuat panggilan ajax saya sinkron dengan menambahkan async: falsedan itu berhasil.

Nilkamal Gotarne
sumber
-9

Metode jQuery.each loop secara sinkron, tetapi Anda tidak dapat menjamin bahwa itu akan melewati item dalam urutan tertentu.

Chris Pietschmann
sumber
21
Tidak, itu akan selalu melewati mereka dalam urutan mereka muncul di dokumen.
Abraham
3
Itu tergantung pada apa yang Anda iterasi. Setiap jaminan eksekusi indeks urutan pada array tetapi tidak membuat jaminan untuk objek (yang harus jelas).
Deadron