2016-03-26 11 views
0

Bazı DOM öğelerini güncelleyen ve ardından setTimeout kullanarak aşağıdaki gibi bir geri arama çağrısında bulunan bir işlev var (bir tane sağlanırsa - aksi halde bir kukla işlev denir):setTimeout ve geri arama - Tarayıcının yenilenen DOM öğeleri oluşturmasına izin vermiyor

 for(var i=0;i<emails.length;i++) { 
      var howmuchdone = Math.ceil(totalchecked*100/totaltocheck); 
      updateprogressbar(1,howmuchdone,howmuchdone+"%",function() {     
       $("#EMAIL_ALL").val($("#EMAIL_ALL").val()+","+getmeadescriptor($.trim(emails[i]))); 
      }); 
      totalchecked = totalchecked + 1; 
     } 

o yürütülürken doğru geri arama, ama setTimeout kullanarak amacım tarayıcı güncellenen DOM öğelerini hale getirdiğini sağlamaktı:

 function updateprogressbar(id,val,label,callback) { 
      var time = 0; 
      if (typeof callback === "function") { 
       var func = callback; 
      } else { 
       var func = function() {}; 
      } 
      $("#progressbar").progressbar({ 
       value: val 
      }); 
      $("#progress-label"+id).html("Overall Progress: "+label); 
      setTimeout(func(),time); 
     } 

döngü bununla denir. Anlayamadığım nedenlerle DOM öğeleri güncellenmiyor.

(UpdateProgressBar döngü için içinde çağrıldığını ve kendisine geçirilen geri arama bazı basit işlemleri yapar anonim bir fonksiyondur -. Ben bu sorunla ilgili olduğunu sanmıyorum rağmen)

Herhangi bir fikir olarak updateprogressbar çağrısında neden tarayıcı oluşturmuyorum?

Teşekkürler!

Yani, vinhHT yorumuna @ sonrasında bu çalışacağım:

   var testfunction = function (value) { 
        $("#EMAIL_ALL").val($("#EMAIL_ALL").val()+","+value; 
       } 

       for(var i=0;i<emails.length;i++) { 
        var howmuchdone = Math.ceil(totalchecked*100/totaltocheck); 
        updateprogressbar(1,howmuchdone,howmuchdone+"%",testfunction(getmeadescriptor($.trim(emails[i])))); 
        totalchecked = totalchecked + 1; 
       } 
+0

Kodunuz, func() 'ın boş bir işlev olduğunu gösterir. Çalışması için DOM manipülasyon kodunuzu bu işleve yerleştirin. Ayrıca, başkalarının işaret ettiği gibi, 0 süresi setTimeout için çok kısadır. – Terry

+0

Geçerli yürütme iş parçacığının bitmesine ve bu şekilde gerçekleşmesi için bir yeniden boyamanın olay döngüsüne dönmesine izin vermelisiniz. Sadece setTimeout() işlevini çağırmak ve kukla bir işleve işaret etmek, setTimeout() işlevini düzgün bir şekilde çağırmış olsanız bile hiçbir şeye yardımcı olmaz. – jfriend00

+0

sonuncusunda ")" eksiksiniz: $ ("# EMAIL_ALL") val ($ ("# EMAIL_ALL"). Val() + "," + getmeadescriptor ($. Trim (e-postalar [i])))); – VinhNT

cevap

0

DÜZENLEME

Şimdi setTimeout çağrısı düzeltmek for döngü kodu, döngüsünüzün her döngüsünün bir sonraki döngü yürütülmeden önce bir rötuş yapmasına izin verebileceğini görüyoruz, döngünün her bir yinelemesini setTimeout() ile başlatmanız gerekir. Bu, kodun döngü yürütmeleri arasındaki olay döngüsüne geri dönmesini sağlar.

// utility function to iterate a loop, but have a short `setTimeout()` 
// pause between each loop iteration 
// assumes mainFn is a synchronous operation 
// doneFn is optional and, if present, will be called when all iterations are done 
function iterateWithRepaint(start, num, incr, mainFn, doneFn){ 
    var end = start + num; 
    function next() { 
     if (start < end) { 
      mainFn(start); 
      start += incr; 
      setTimeout(next, 20); 
     } else { 
      if (typeof doneFn === "function") { 
       doneFn(); 
      } 
     } 
    } 
    next(); 
} 

// got rid of callback in here since it was not helpful 
// and added loop index as an argument 
function updateprogressbar(id, val, label, i) { 
    var time = 0; 
    $("#progressbar").progressbar({ 
     value: val 
    }); 
    $("#EMAIL_ALL").val($("#EMAIL_ALL").val()+","+getmeadescriptor($.trim(emails[i]))); 
    $("#progress-label"+id).html("Overall Progress: "+label); 
}  

// call your function with a timer delay between each iteration 
iterateWithRepaint(0, emails.length, 1, function(i) { 
    var howmuchdone = Math.ceil(totalchecked*100/totaltocheck); 
    updateprogressbar(1,howmuchdone,howmuchdone+"%", i); 
    totalchecked = totalchecked + 1; 
}); 

tarayıcı bir relayout zorlar böylece sadece doğru tam relayout sonra kaydedilmemiştir belli CSS özelliklerini isteyerek yeniden akışlara ve bazen bir rötuş tetikleyecek bazı başka yolları vardır ama: Böyle bunu yapabilir Bu yöntem, tarayıcıların geliştirilmiş performansa yönelik gereksiz yeniden boyamaları dikkate aldıklarını optimize etmeye çalıştıkları için zor ve hareketli bir hedef olduğunu kanıtlamıştır. Yani, bu tekniklere güvenmemeyi tercih ediyorum.

Sizin setTimeout()

yanlış bildirilmiş, ancak bundan daha sorununuza daha vardır: döngü kodundan önce


öncesinde Cevap açıkladı. Uygun şekilde bildirilmiş olsa bile, kendi sayfanızın referanduma izin vermemesine rağmenA setTimeout(). Tüm bu gelecek gelecekte çalıştırmak için bazı kod zamanlama. Bunun yerine, şimdi kodu çalıştırmayı durdurup gelecekteki kodu INTO setTimeout geri çağır. Sadece geçerli iş parçacığının olay döngüsüne geri dönmesine izin verir ve ardından ekrana yeniden yazdırma şansı verir.

Bilginize, senin setTimeout() böyle olmalı:

kodunda bir şey düzeltemez olacak gösteriyor ki değişen
setTimeout(func,time); 

Ama çünkü func() sen aslında hiçbir şey ve bu nedenle olmaz vermez göstermek olarak aslında bir rötuş izin verin. TÜM Gelecek kodunuz func() içerideyse VE, mevcut iş parçanızda setTimeout() aramasından sonra çalıştırılacak başka kod olmadıysa, büyük olasılıkla bir yeniden boyamaya izin verilir.

Bize kodunuzun geri kalanını boyamayı geciktirecek şekilde gösterirseniz, muhtemelen size daha özel olarak yardımcı olabiliriz. Gösterdiğiniz kod, bir rötuşu kendi kendine ertelemez.

+0

Teşekkürler @ jfriend00. Gelecekteki kodumun tamamı, updateprogressbar işlevine iletilen geri arama içinde.var func geri çağrıya ayarlandı ve setTimeout içinde çağrıldı, bu yüzden çalışmalı mıyım? Herhangi bir geri arama yapılmazsa, herhangi bir yeniden boya göremediğimi tamamen takdir ediyorum. –

+0

@ChrisJones - Sorunuzda "updateprogressbar'ın for döngüsünde çağrıldığını" söylüyorsunuz. 'For' döngüsünün süresi, doğru bir şekilde bildirilen' setTimeout() 'geri aramada ne olursa olsun, 'for' döngüsü tamamlanana kadar replikleri engeller. "For" döngüsünün repaints'i engellemesine yardımcı olmak istiyorsanız, 'for' döngüsü dahil olmak üzere daha fazla kod görmemiz gerekir. – jfriend00

+0

Teşekkürler @ jfriend00 - lütfen yukarıdaki çağrıyı gösteren döngüyi görüntüleyin. Burada bir şeyi kaçırıyor olabilirim - elde etmeye çalıştığım her şey, döngü içi her birimin sonunda güvenilir bir şekilde yeniden boyamaktır - bir süre bununla uğraştığım için başka herhangi bir öneri en çok takdir edilecektir! –

2

Kaldır() sizin setTimeout içinde

As setTimeout(func,time); 

Edit jfriend00 yorumuna sonra:

  1. declare işlevi şu şekilde doğru şekilde:

    var fonk = function() { // iş buraya } Doğru

  2. setTimeout olarak kodunda callback'inde yukarıdaki çağrısı (fonksiyon, zaman); soru olarak

3 düzenlemeyi yapan: if-else bloğu dışında fonk beyan, sen ifşa ettik,

function updateprogressbar(id, val, label, callback) { 
    var time = 0; 
    var func; 
    if (typeof callback === "function") { 
     func = callback; 
    } else { 
     func = function() {}; 
    } 
    $("#progressbar").progressbar({ 
     value: val 
    }); 
    $("#progress-label" + id).html("Overall Progress: " + label); 
    setTimeout(func, time); 
} 
+0

Onların "setTimeout()" yanlıştı, ama göstermedikleri kodda, aslında bu aslında problemlerini çözüyor, çünkü func() 'aslında hiçbir şey yapmıyor, bu yüzden bir rötuşlamayı geciktirmiyor. – jfriend00

+0

func, var func = function() {/// mantık kodu}; – VinhNT

+0

Önemli olan, cevabınızın sorunu çözmemesidir, çünkü bahsettiğiniz sorun, yanlış bir kod parçasıdır, ancak kod başına, sorunun bir rötuş işlemini geciktirmediğini göstermesi. Yani, "Bunlar aradığınız droidler değil" dedikleri gibi. – jfriend00

İlgili konular