setTimeout() vs setInterval()
setTimeout() wywołuje funkcję jeden raz po określonym czasie, a setInterval() wywołuje ją cyklicznie, aż zatrzymasz je przez clearInterval().
Porównanie w tabeli
#Ile razy wywołuje funkcję
- setTimeout()
- Raz, po upływie czasu
- setInterval()
- Wielokrotnie, co podany odstęp
Pierwsze wywołanie
- setTimeout()
- Po delay milisekundach
- setInterval()
- Też po delay, nie od razu
Jak zatrzymać
- setTimeout()
clearTimeout(id)przed wywołaniem- setInterval()
clearInterval(id), inaczej działa bez końca
Ryzyko wycieku pamięci
- setTimeout()
- Niskie, wywołuje się tylko raz
- setInterval()
- Częste, zapomniany interwał działa w nieskończoność
Gdy pojedyncze wywołanie trwa długo
- setTimeout()
- Bez znaczenia, jest tylko jedno
- setInterval()
- Wywołania mogą się logicznie nakładać
Typowe użycie
- setTimeout()
- Jednorazowe opóźnienie, debounce
- setInterval()
- Odliczanie i proste powtarzanie w tle
Przykład
#console.log('Start')
const timer = setInterval(() => console.log('Interval tick'), 200)
setTimeout(() => {
clearInterval(timer)
console.log('Timeout po 500 ms, interwał zatrzymany')
}, 500)Definicja i zastosowanie
#Obie funkcje planują wywołanie callbacku po podanej liczbie milisekund i nie blokują reszty kodu, który wykona się dalej od razu. Obie zwracają identyfikator, który przekazujesz do odpowiedniej funkcji czyszczącej, żeby odwołać zaplanowane wywołanie. Podany czas to tylko minimalne opóźnienie, nie gwarancja dokładności.
setTimeout() wywołuje funkcję jeden raz i kończy działanie. setInterval() wywołuje ją wielokrotnie, co ten sam odstęp, aż do wywołania clearInterval(), przy czym pierwsze wywołanie następuje też po pierwszym odstępie, nie od razu. Zapomniany interwał pracuje w nieskończoność, nawet gdy nikt już nie potrzebuje jego wyników, co jest częstą przyczyną wycieków pamięci. Gdy pojedyncze wywołanie może trwać dłużej niż odstęp, na przykład zapytanie do serwera, bezpieczniejszy jest samo-planujący się łańcuch setTimeout().
Do jednorazowego opóźnienia i do mechanizmów typu debounce używaj setTimeout(). Do prostego, stałego powtarzania, jak odliczanie czasu, setInterval() wystarczy, ale pamiętaj o clearInterval(), gdy przestaje być potrzebny.
Składnia
#const timeoutId = setTimeout(callback, delay)
const intervalId = setInterval(callback, delay)Więcej przykładów
#let calls = 0
const id = setInterval(() => {
calls += 1
if (calls === 3) {
clearInterval(id)
console.log('Łącznie wywołań:', calls)
}
}, 150)function debounce(fn, ms) {
let timer
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => fn(...args), ms)
}
}
const saveDraft = debounce((text) => console.log('Zapisano szkic:', text), 200)
saveDraft('H')
saveDraft('He')
saveDraft('Hello')Każde wywołanie saveDraft() czyści poprzedni timer przez clearTimeout(). Zapisany zostaje tylko ostatni szkic, 200 ms po ostatnim wywołaniu.
Dobre praktyki
#- Zawsze zapisuj identyfikator zwrócony przez
setInterval()i wywołujclearInterval(), gdy powtarzanie nie jest już potrzebne. - Gdy pojedyncze wywołanie może trwać dłużej niż odstęp, na przykład zapytanie do serwera, użyj łańcucha
setTimeout()zamiastsetInterval(). - Do debounce (reakcja po przerwie w pisaniu) buduj na
setTimeout(), nie nasetInterval().
Powiązane hasła
#- setTimeout()Uruchamia funkcję jeden raz, po upływie podanej liczby milisekund.
- setInterval()Wywołuje funkcję cyklicznie, co podany odstęp czasu, aż do zatrzymania przez clearInterval().
- PromiseObiekt reprezentujący wynik operacji, który pojawi się w przyszłości: wartość przy sukcesie albo błąd.
- awaitWstrzymuje funkcję async do czasu rozstrzygnięcia obietnicy i zwraca jej wartość albo rzuca jej błąd.
Widzisz błąd albo brakuje przykładu? Napisz do nas.