2016-04-13 15 views
1

Soru asked before oldu, ama neredeyse dört yıl önceydi ve belki daha iyi bir çözüm var.

Ajax aracılığıyla bazen ek verilerin getirildiği $ .each-loop'um var.

Alınan verilerle bir nesneyi buluyorum, döngüden sonra HTML'den nesne üreten bir işlev var. Sorun, ajax verisi gelmeden önce döngüsünün bitmesidir. HTML üreten işleve bir uyarı koyarsam içerik düzgün yükleniyor.

Sadece döngü ve tüm ajax çağrıları bittiğinde HTML üreteci işlevini çağıran bir çözüm arıyorum. Belki başlangıç ​​Ajax isteklerini saymak ve hepsi bittiğinde beklemek bir çözümdür?

jQuery ertelenmiş çözüm benim için doğru çözüm olduğuna inanıyorum ama her şeyin döngü içinde kaldığı örnekleri buluyorum. Birisi yardım edebilir mi?

Ben en önemli şeylerden için kodumu aşağı çalmıştır: Birisi bunu nasıl bir tavsiye benim verebilir

//goes through each testplace -->main loop 
$.each(jsobject, function(key, value) 
{ 
//build object together... 
    for (var i = 0, numComputer = jenkinsComputer.contents.computer.length; i < numComputer; i++) 
    { 
    //If the testplace is in both objects then fire AJAX request 
    if (jenkinsComputer.contents.computer[i].displayName == key) //<<<This can happen only once per $.each loop, but it does not happen every time 
    { 
     //next $.each-iteration should only happen when received the JSON 
     var testplaceurl = jenkinsComputer.contents.computer[i].executors[0].currentExecutable.url; 
     $.when($.getJSON("php/ba-simple-proxy.php?url=" + encodeURI(testplaceurl) + "api/json?depth=1&pretty=1")).done(function(jenkinsUser) 
     { 
     //build object together... 
     }); 
    } 
    } 

}); //End of main Loop ($.each) 
generateHTML(builtObject); 

harika olurdu.

+1

Sadece küçük bir ipucu: AJAX bir döngü içinde iyi bir fikir değildir. Daha basit görünebilir, ancak sunucu tarafının döngü yapmasına izin vermek daha iyidir. –

+0

Tüm script yerel ağımızda çalışıyor ve çoğu zaman sadece 5-10 kısa ajax çağrıları var, bu yüzden burada bir ağ sorunu yok. Bunun için bir javascript çözümü varsa harika olurdu. – bademeister

cevap

0

Böyle bir şey yapacağını:

var thingstodo = $(jsobject).length; 
var notfired = true; 
$.each(jsobject, function(key, value) 
{ 
//build object together... 
    for (var i = 0, numComputer = jenkinsComputer.contents.computer.length; i < numComputer; i++) 
    { 
    //If the testplace is in both objects then fire AJAX request 
    if (jenkinsComputer.contents.computer[i].displayName == key) //<<<This can happen only once per $.each loop, but it does not happen every time 
    { 
     //next $.each-iteration should only happen when received the JSON 
     var testplaceurl = jenkinsComputer.contents.computer[i].executors[0].currentExecutable.url; 
     $.when($.getJSON("php/ba-simple-proxy.php?url=" + encodeURI(testplaceurl) + "api/json?depth=1&pretty=1")).done(function(jenkinsUser) 
     { 
     //build object together... 
     thingstodo--; 
     if(thingstodo === 0 && notfired){ 
      notfired = false; 
      generateHTML(buildObject); 
     } 
     }); 
    }else{ 
     thingstodo--; 
    } 
    } 

}); //End of main Loop ($.each) 
if(thingstodo === 0 && notfired){ 
    generateHTML(buildObject); 
} 
0

Bu, çözümle ilgili kısa test edilmemiş bir örnektir. Umarım bu size fikir verir.

// I guess that jsobject is array .. 
// if it is not object you can use something like: 
// var keys = Object.getOwnPropertyNames(jsobject) 
(function() { 
    var dfd = $.Deferred(); 

    function is_not_finished() { 
     return jsobject.length > 0 && jenkinsComputer.contents.computer.length > 0; 
    } 

    (function _handleObject() { 
     var key = jsobject.shift(); 
     var displayName = jenkinsComputer.contents.computer.shift().displayName; 

     if (displayName == key) //<<<This can happen only once per $.each loop, but it does not happen every time 
     { 
      //next $.each-iteration should only happen when received the JSON 
      var testplaceurl = jenkinsComputer.contents.computer[i].executors[0].currentExecutable.url; 
      $.getJSON("php/ba-simple-proxy.php?url=" + encodeURI(testplaceurl) + "api/json?depth=1&pretty=1").done(function(jenkinsUser) 
      { 
       //build object together... 
       if(is_not_finished()) { 
        setTimeout(_handleObject,0); 
       } else { 
        dfd.resolve(); 
       } 
      }); 
     } else if (is_not_finished()) { 
      setTimeout(_handleObject,0); 
     } else { 
      dfd.resolve(); 
     } 
    }()); 

    return dfd.promise(); 
}()).done(function() { 
    generateHTML(builtObject); 
}); 
+0

Eşzamansız çalışmasına izin vermek yerine ajax isteği yaparken tüm yürütmeyi engelliyorsunuz. – Danmoreng

+0

Hmmm. Aslında $ .each sinchronous. Çözümleriniz, isteklerini aynı anda gönderdiğinden, alınan verilerin dizisi önemli değilse, OK olur. Buradaki anahtar "alınırken sonraki yinelemeler" dir. Ayrıca, söze bağlı $ .eachAsinc gibi bir şey geliştirebiliriz. Ayrıca senin durumunda $ .when gereksiz çünkü $ .getJSON iadesi söz veriyorum. –