2014-02-14 173 views
1

這就是我所擁有的。我的問題是,each循環不等待setTimeout來完成它的工作。在執行slider.goToNextSlide之前,我有2 console.log('elmDuration = ')...。這是錯誤的。如果這是一個服務器端代碼,我會使用生成器函數和yield,但不會。setTimeout jQuery的每個循環

$('li').each(function(index, elm){ 
     var image = $(elm).find('img')[0]; 
     var video = $(elm).find('video')[0]; 
     var media = image || video; 

     var elmDuration = $(media).attr('data-duration'); 
     console.log("elmDuration = ", elmDuration); 
     (function(){ 
      setTimeout(slider.goToNextSlide, elmDuration * 1000); 
     })(); 
}); 

我困住了這個。謝謝。

回答

3

如果要前進到下一個元素時超時完成後,你必須這樣做手工:

var $lis = $('li'); 
var index = 0; 

function next(index) { 
    var elem = $lis[index]; 
    var image = $(elm).find('img')[0]; 
    var video = $(elm).find('video')[0]; 
    var media = image || video; 

    // if there is always going to be either an img **or** a video element, 
    // you can directly do 
    // var elmDuration = $(elem).find('img, video').attr('data-duration'); 
    var elmDuration = $(media).attr('data-duration'); 
    console.log("elmDuration = ", elmDuration); 

    setTimeout(function() { 
     slider.goToNextSlide(); 
     if (index < ($lis.length - 1)) { 
      next(++index); 
     } 
    }, elmDuration * 1000); 
} 

next(index); 
3

each循環不會等待setTimeout。在setTimeout開始發射之前,它將執行$('li')中的所有元素。 setTimeout的目的是讓調用它的代碼不受中斷地執行,並在發生超時時執行第一個參數。

2

如果您希望它在循環內執行,您必須將代碼從setTimeout中取出。 SetTimeout是以毫秒爲單位執行代碼的一種方式,但直到單個JavaScript線程可用時纔會執行。循環會使線程繁忙,因此所有seTimeout都必須等到結束。

+0

理解。但是在執行setTimeout內的代碼之前,我需要等待元素特定的秒數。我該如何處理? – alix

+1

你已經在做。不需要在另一個函數中包裝'setTimeout'調用。 – Igor