Odpowiedzi:
Istnieją następujące:
setTimeout(function, milliseconds);
funkcja, którą można przekazać, po upływie której funkcja zostanie wykonana.
Zobacz: Metoda oknasetTimeout()
.
function_reference
chyba że zostanie to uwzględnione ()
. To znaczyfunction_reference
To tylko to - odniesienie; przekazanie function_reference()
wywołałoby funkcję natychmiast.
Aby dodać do tego, o czym wszyscy inni mówili setTimeout
: jeśli chcesz wywołać funkcję z parametrem w przyszłości, musisz skonfigurować anonimowe wywołania funkcji.
Musisz przekazać funkcję jako argument, aby mogła zostać wywołana później. W efekcie oznacza to brak nawiasów za nazwą. Następujące wywołają alert natychmiast i wyświetli „Hello world”:
var a = "world";
setTimeout(alert("Hello " + a), 2000);
Aby to naprawić, możesz albo wpisać nazwę funkcji (jak zrobiła to Flubba), albo możesz użyć funkcji anonimowej. Jeśli musisz przekazać parametr, musisz użyć funkcji anonimowej.
var a = "world";
setTimeout(function(){alert("Hello " + a)}, 2000);
a = "Stack Overflow";
Ale jeśli uruchomisz ten kod, zauważysz, że po 2 sekundach wyskakujące okienko powie „Hello Stack Overflow”. Jest tak, ponieważ wartość zmiennej a zmieniła się w ciągu tych dwóch sekund. Aby po dwóch sekundach powiedzieć „Witaj świecie”, musisz użyć następującego fragmentu kodu:
function callback(a){
return function(){
alert("Hello " + a);
}
}
var a = "world";
setTimeout(callback(a), 2000);
a = "Stack Overflow";
Poczeka 2 sekundy, a następnie wyskakujące okienko „Hello world”.
Jeśli naprawdę chcesz mieć funkcję blokującą (synchroniczną) delay
(cokolwiek), dlaczego nie zrobić czegoś takiego:
<script type="text/javascript">
function delay(ms) {
var cur_d = new Date();
var cur_ticks = cur_d.getTime();
var ms_passed = 0;
while(ms_passed < ms) {
var d = new Date(); // Possible memory leak?
var ticks = d.getTime();
ms_passed = ticks - cur_ticks;
// d = null; // Prevent memory leak?
}
}
alert("2 sec delay")
delay(2000);
alert("done ... 500 ms delay")
delay(500);
alert("done");
</script>
delay
ing (aby odpowiedzieć na to pytanie ). Czy jest na to jakiś sposób?
Musisz użyć setTimeout i przekazać mu funkcję zwrotną. Powodem, dla którego nie możesz korzystać ze snu w javascript, jest to, że w międzyczasie blokowałbyś całą stronę. Niezły plan. Skorzystaj z modelu zdarzeń Javascript i bądź szczęśliwy. Nie walcz z tym!
Możesz także użyć funkcji window.setInterval (), aby wielokrotnie uruchamiać kod w regularnych odstępach czasu.
setTimeout()
robi to raz, setInterval()
robi to wielokrotnie. Jeśli chcesz, aby Twój kod był uruchamiany co 5 sekund, setInterval()
jest przeznaczony dla zadania.
Aby dodać wcześniejsze komentarze, chciałbym powiedzieć, co następuje:
setTimeout()
Funkcji w JavaScript nie wstrzymać wykonanie skryptu per se, ale jedynie informuje kompilator do wykonania kodu kiedyś w przyszłości.
Nie ma funkcji, która może faktycznie wstrzymać wykonywanie wbudowane w JavaScript. Możesz jednak napisać własną funkcję, która robi coś w rodzaju bezwarunkowej pętli, dopóki czas nie zostanie osiągnięty, używając Date()
funkcji i dodając potrzebny przedział czasu.
Jeśli potrzebujesz tylko przetestować opóźnienie, możesz użyć tego:
function delay(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
A jeśli chcesz opóźnić o 2 sekundy, robisz:
delay(2000);
Może nie być najlepszy do produkcji. Więcej na ten temat w komentarzach
dlaczego nie możesz umieścić kodu za obietnicą? (wpisany na czubku głowy)
new Promise(function(resolve, reject) {
setTimeout(resolve, 2000);
}).then(function() {
console.log('do whatever you wanted to hold off on');
});
Naprawdę podobało mi się wyjaśnienie Mauriusa (najwyższa pozytywna odpowiedź) z trzema różnymi metodami wywoływania setTimeout
.
W moim kodzie chcę automatycznie nawigować do poprzedniej strony po zakończeniu zdarzenia zapisu AJAX. Zakończenie zdarzenia zapisywania ma niewielką animację w CSS, co wskazuje, że zapis był udany.
W moim kodzie znalazłem różnicę między pierwszymi dwoma przykładami:
setTimeout(window.history.back(), 3000);
Ten nie czeka na przekroczenie limitu czasu - funkcja back () jest wywoływana prawie natychmiast, bez względu na to, jaki numer wprowadzę dla opóźnienia.
Jednak zmieniając to na:
setTimeout(function() {window.history.back()}, 3000);
To robi dokładnie to, na co liczyłem.
Nie jest to specyficzne dla operacji back (), to samo dzieje się z alert()
. Zasadniczo w przypadku alert()
zastosowanego w pierwszym przypadku czas opóźnienia jest ignorowany. Kiedy odrzucam wyskakujące okienko, animacja dla CSS jest kontynuowana.
Dlatego poleciłbym drugą lub trzecią metodę, którą opisuje, nawet jeśli używasz wbudowanych funkcji i nie używasz argumentów.
Miałem kilka komend ajax, które chciałem uruchomić z opóźnieniem pomiędzy nimi. Oto prosty przykład jednego ze sposobów, aby to zrobić. Jestem przygotowany na rozerwanie na strzępy ze względu na moje niekonwencjonalne podejście. :)
// Show current seconds and milliseconds
// (I know there are other ways, I was aiming for minimal code
// and fixed width.)
function secs()
{
var s = Date.now() + ""; s = s.substr(s.length - 5);
return s.substr(0, 2) + "." + s.substr(2);
}
// Log we're loading
console.log("Loading: " + secs());
// Create a list of commands to execute
var cmds =
[
function() { console.log("A: " + secs()); },
function() { console.log("B: " + secs()); },
function() { console.log("C: " + secs()); },
function() { console.log("D: " + secs()); },
function() { console.log("E: " + secs()); },
function() { console.log("done: " + secs()); }
];
// Run each command with a second delay in between
var ms = 1000;
cmds.forEach(function(cmd, i)
{
setTimeout(cmd, ms * i);
});
// Log we've loaded (probably logged before first command)
console.log("Loaded: " + secs());
Możesz skopiować blok kodu i wkleić go do okna konsoli i zobaczyć coś takiego:
Loading: 03.077
Loaded: 03.078
A: 03.079
B: 04.075
C: 05.075
D: 06.075
E: 07.076
done: 08.076
funkcja opóźnienia:
/**
* delay or pause for some time
* @param {number} t - time (ms)
* @return {Promise<*>}
*/
const delay = async t => new Promise(resolve => setTimeout(resolve, t));
użycie async
funkcji wewnętrznej :
await delay(1000);
Jak już powiedziano, setTimeout jest najbezpieczniejszym zakładem.
Ale czasami nie można oddzielić logiki do nowej funkcji, wówczas można użyć funkcji Date.now (), aby uzyskać milisekundy i samodzielnie wykonać opóźnienie ....
function delay(milisecondDelay) {
milisecondDelay += Date.now();
while(Date.now() < milisecondDelay){}
}
alert('Ill be back in 5 sec after you click OK....');
delay(5000);
alert('# Im back # date:' +new Date());