2012-05-12 3 views
36

W prostym setIntervalJak od razu uruchomić pętlę setInterval?

setInterval(function() { 
     // Do something every 9 seconds 
}, 9000); 

Pierwsze działanie nastąpi po 9 sekund (t=9s). Jak zmusić pętlę do natychmiastowego wykonania pierwszej akcji (t=0)?

Myślę, że to ze względu na mechanizm setInterval mieć pętlę Delay - Action - Delay - Action ...; zamiast pętli Action - Delay - Action - Delay ....

EDIT: Moja funkcja jest rzeczywiście pętla jak

setInterval(function(){ 
$('.test').each(function(idx){ 
    var duration = 1000; 
    $(this).delay(duration*idx); 
    Some stuff here 
}); 
}, 4000); 

Odpowiedz

76

Keep it simple. Możesz użyć nazwanej funkcji zamiast anonimowej funkcji; zadzwoń i ustaw dla niego przedział.

function doSomething() { 
    console.log("tick"); 
} 
doSomething(); 
setInterval(doSomething, 9000); 

utworzyć obszar jeśli konieczne:

(function() { 
    function doSomething() { 
     console.log("tick"); 
    } 
    doSomething(); 
    setInterval(doSomething, 9000); 
})(); 

Wreszcie, następujące prace bez tworzenia lub wpływających x:

setInterval(function x() { 
    console.log("tick"); 
    return x; 
}(), 9000); 
+0

Ładne, proste rozwiązanie, dzięki! –

+1

Pierwsza część tej odpowiedzi będzie się stopniowo spowalniała, ponieważ nowa 'setInterval' jest tworzona w każdej pętli. Można to naprawić, zastępując 'window.setInterval' przez' setTimeout'. – spikespaz

17

Czasami używam ten wzór ...

(function me() { 
    // Do something every 9 seconds 

    setTimeout(me, 9000); 
})(); 

To nie jest to samo, ponieważ będzie czekać, aż zrobi coś, co zostanie zrobione przed odczekaniem ~ 9 sekund na ponowne wywołanie. Ale często jest to przydatne, więc zdarzenia w kolejce zdarzeń nie są niepotrzebnie ułożone (jednak mało prawdopodobne jest, że uruchomienie kodu zajmie 9 sekund :)

Należy zauważyć, że w starszych wersjach IE, me wycieknie do zakresu zewnętrznego .

+0

* "Zauważ, że w starszych IE, ja wycieknie do zewnętrznego zakresu." * I dwie różne funkcje są tworzone, w różnych czasach, z tym samym kodem. * Pierwszy * czas działania twojego kodu, to jedna z nich; wszystkie kolejne czasy to ten drugi. Dziwne, ale prawdziwe. –

+0

Chciałbym, żeby to działało bezproblemowo we wszystkich przeglądarkach. Jest tak czysty. Które wersje IE działają nieprawidłowo? – thekingoftruth

+0

@thekingoftruth Powinno * działać * bezproblemowo, po prostu wycieknie identyfikatora 'mi' w IE. Z pamięci jest <= IE8, który ma problem. – alex

2

Użyj nazwanej funkcji i wywołaj ją i przypisz do przedziału.

var myFnc = function() { 
    // Do something every 9 seconds 
}; 
setInterval(myFnc, 9000); 
myFnc(); 

Inną opcją jest użycie funkcji setTimeout.

var myFnc = function() { 
    // Do something every 9 seconds 
    setTimeout(myFnc, 9000); 
}; 
myFnc(); 
+2

To nie jest nazwana funkcja.Jest to anonimowa funkcja przypisana do zmiennej. * Zmienna * ma nazwę, funkcja nie działa (co jest dobre dla tego, co robisz, inne niż niektóre debugery nie będzie w stanie pokazać Ci przydatnej nazwy w stosach połączeń, a takie [inne, najnowsze narzędzia Chrome Dev i Firebug są całkiem sprytne]). –

12

setInterval() jest naprawdę brzydką funkcją. Używam tej odkażonej wersji, która natychmiast wywołuje funkcję i zajmuje czas w sekundach, PRZED parametrem funkcji, tak więc wywołanie jej z wbudowaną definicją funkcji rzeczywiście wygląda rozsądnie.

function startInterval(seconds, callback) { 
    callback(); 
    return setInterval(callback, seconds * 1000); 
}