jQuery“ each ()” ฟังก์ชั่นซิงโครนัสหรือไม่


133

พิจารณาสถานการณ์นี้เพื่อตรวจสอบความถูกต้อง:

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 block ถูกดำเนินการก่อนที่การวนซ้ำจะเสร็จสิ้น ฉันคาดว่าเนื้อหาvalidateFormจะถูกดำเนินการพร้อมกัน แต่ดูเหมือนว่าeach()ฟังก์ชันjQuery จะดำเนินการแบบอะซิงโครนัส ฉันถูกไหม? ทำไมถึงไม่ได้ผล?


2
รหัสตรวจสอบความถูกต้องมีลักษณะอย่างไร? eachเป็นแบบซิงโครนัส แต่รหัสข้างในอาจไม่ใช่ ...
lonesomeday

1
eachตัวมันเองถูกประมวลผลพร้อมกัน คุณกำลังเริ่มการดำเนินการ async ของคุณเองจากภายในลูปหรือไม่?
จอน

3
ปัญหาที่คล้ายกันที่นี่ .. คุณแก้ปัญหาอย่างไร
sakthig

มันนานมากแล้วจำไม่ได้ แต่ฉันรู้ว่าคำตอบนั้นช่วยฉันได้ ดังนั้นฉันอาจใช้บล็อกรหัส async ในรหัสตรวจสอบความถูกต้องของฉัน (เช่นพยายามตรวจสอบที่อยู่โดยใช้คำขอ ajax)
Saeed Neamati

1
อืม .. ฉันแก้ไขด้วยวิธีนี้ .. ฉันกำลังทำ "return false" ภายในแต่ละฟังก์ชันซึ่งใช้งานไม่ได้ฉันเดาว่า .. ตอนนี้กำลังรักษาค่าสถานะภายในแต่ละฟังก์ชันและส่งคืนค่าสถานะนั้นเมื่อสิ้นสุดการตรวจสอบความถูกต้อง ..
sakthig

คำตอบ:


159

ใช่eachวิธีjQuery เป็นแบบซิงโครนัส JavaScript เกือบทั้งหมดซิงโครนัส ข้อยกเว้นเพียงอย่างเดียวคือ AJAX ตัวจับเวลา ( setTimeoutและsetInterval) และ HTML5 Web Workers
ปัญหาของคุณอาจอยู่ที่อื่นในรหัสของคุณ


7

jQueryเป็นไลบรารี javascript เท่านั้น ยกเว้นajax, setTimeoutและมีอะไรที่สามารถดำเนินการถ่ายทอดสดในsetInterval JavaScriptดังนั้นeachจะดำเนินการพร้อมกันอย่างแน่นอน มีข้อผิดพลาด js อยู่ในeachรหัสบล็อกแน่นอน คุณควรตรวจสอบข้อผิดพลาดในคอนโซล

หรือคุณสามารถดูคิว jQuery เพื่อเรียกใช้ฟังก์ชันใด ๆ ในคิว สิ่งนี้จะทำให้แน่ใจว่าฟังก์ชันที่อยู่ในคิวจะทำงานได้ก็ต่อเมื่อการเรียกใช้โค้ดก่อนหน้าเสร็จสมบูรณ์


7
นอกจากนี้ยังมีสัญญา ... แค่พูด :)

6

อีกเหตุผลหนึ่งที่ถามคำถามนั้นก็คือแต่ละคนจะหยุดการทำซ้ำเมื่อฟังก์ชัน (.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 falseใน.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.e แต่ละวิธีจะวนซ้ำแบบซิงโครนัส แต่คุณไม่สามารถรับประกันได้ว่าจะวนซ้ำรายการตามลำดับใด ๆ


21
ไม่มันจะวนซ้ำตามลำดับที่ปรากฏในเอกสารเสมอ
อับราฮัม

3
ขึ้นอยู่กับสิ่งที่คุณกำลังทำซ้ำ แต่ละรายการรับประกันการดำเนินการคำสั่งดัชนีบนอาร์เรย์ แต่ไม่รับประกันสำหรับวัตถุ (ซึ่งควรชัดเจน)
Deadron
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.