Vjerovatno vam je u nekom trenutku zatrebalo da vaša web stranica nešto uradi, ali ne odmah, već nakon nekoliko sekundi. Da bi se to postiglo, JavaScript nudi osnovni alat pod nazivom `setTimeout` , koji u suštini djeluje kao tajmer koji, kada dostigne nulu, pokreće određenu radnju. To je jedna od onih funkcija koje na prvi pogled izgledaju jednostavno, ali imaju svoje posebnosti i tehničke detalje koje vrijedi znati kako biste izbjegli greške tokom programiranja.
Iako ga stalno vidimo u pregledniku, važno je pojasniti da ova metoda nije dio samog osnovnog JavaScript jezika, već je pruža okruženje za izvršavanje . To znači da ga, iako ga koristimo u Chromeu ili Firefoxu, nalazimo i u Node.js-u, iako s nekim razlikama u onome što sistem vraća. Hajde da detaljno razložimo kako funkcioniše, od osnova do naprednih trikova kako bi vaše aplikacije radile glatko.
Šta je tačno setTimeout i kako se koristi?

Jednostavno rečeno, ova globalna metoda vam omogućava da zakažete izvršavanje dijela koda ili funkcije nakon isteka određenog vremena . Nakon što tajmer istekne i funkcija se izvrši, proces se završava; to jest, ne ponavlja se automatski. Osnovna sintaksa zahtijeva da navedete šta želite da uradite i koliko dugo čekate, uvijek izraženo u milisekundama (imajte na umu da 1000 ms iznosi jednu sekundu).
Da bismo ga pokrenuli, možemo proslijediti funkciju kao prvi argument. Međutim, iz historijskih razloga, moguće je proslijediti i niz teksta koji sadrži kod, iako se danas to smatra lošom praksom i mnogo je bolje koristiti funkcije strelica ili reference na imenovane funkcije kako bi kod bio čist i siguran.
Parametri i fleksibilnost u izvršenju

Kada konfiguriramo tajmer, drugi parametar je delay . Ako ništa ne odredimo, podrazumijevana vrijednost je 0. Ali evo zanimljivog dijela: šta ako našoj funkciji trebaju eksterni podaci? Postoje dva glavna načina za rješavanje ovoga. Prvi je putem anonimne funkcije koja obavija originalni poziv, omogućavajući nam da proslijedimo bilo koje argumente koje želimo. Drugi, i elegantniji, način je iskorištavanje činjenice da nam `setTimeout` omogućava dodavanje dodatnih argumenata počevši od trećeg parametra, koji se direktno mapiraju na funkciju povratnog poziva.
Upravljanje otkazivanjima pomoću clearTimeout-a

Ponekad život krene neočekivanim tokom i moramo otkazati planirani zadatak koji još nije pokrenut. Da bismo to uradili, moramo znati da `setTimeout` vraća jedinstveni identifikator (`timerId`). U preglednicima, ovaj ID je obično broj, dok je u Node.js-u to složeniji objekat. Ako ovu vrijednost pohranimo u varijablu, možemo pozvati funkciju ` clearTimeout(timerId)` da bismo otkazali operaciju i spriječili izvršavanje koda, čime ćemo uštedjeti sistemske resurse.
Poređenje: setTimeout vs setInterval

Vrlo je često brkati ove dvije metode. Dok `setTimeout` izvršava funkciju samo jednom, `setInterval` je izvršava više puta svaki put kada istekne definirani interval. Međutim, postoji napredni trik: ugniježđena `setTimeout` . Ovo uključuje pozivanje novog `setTimeout` odmah na kraju izvršavanja trenutne funkcije.
Ova tehnika je mnogo fleksibilnija od `setInterval` jer garantuje stvarno i konstantno kašnjenje između kraja jednog zadatka i početka sljedećeg. Sa `setInterval`, ako funkcija izvršava duže od vremena intervala, pozivi se mogu gomilati ili izvršavati bez pauziranja. Nasuprot tome, ugniježđivanje vam omogućava dinamičko podešavanje vremena, što je od vitalnog značaja ako, na primjer, šaljete zahtjeve serveru koji bi mogao biti preopterećen i trebate povećati interval čekanja.
Zanimljiv slučaj nultog kašnjenja i ograničenja
Ako koristite `setTimeout(func, 0)` , mogli biste pomisliti da se funkcija izvršava trenutno, ali to nije slučaj. Ono što se dešava jeste da raspoređivač stavlja zadatak u red čekanja da se izvrši što je prije moguće , ali uvijek nakon što se trenutni skript potpuno završi. To je način da se kaže: "Završi ono što radiš i čim prije možeš, uradi ovo."
Nadalje, važno je napomenuti da preglednici nameću minimalno ograničenje od 4 ms za ugniježđene tajmere nakon što su se pokrenuli pet puta uzastopno. Ovo je ostatak iz starijih verzija kako bi se spriječilo rušenje preglednika. Međutim, preciznost nije apsolutna; ako je CPU preopterećen ili kartica radi u pozadini , preglednik može odgoditi izvršenje do 300 ms ili čak cijelu sekundu kako bi uštedio energiju baterije.
Implementacija u modernim okvirima
Ova metoda se savršeno prevodi u alate poput Reacta ili Angulara. U Reactu , idealan pristup je umotati `setTimeout` unutar hook-a `useEffect` kako bi se kontrolirao životni ciklus komponente i osiguralo da se tajmer briše pomoću funkcije return, čime se sprječava curenje memorije. U Angularu se može lako integrirati u konstruktor komponente ili hook-ove životnog ciklusa kako bi se pokrenula upozorenja ili učitali asinhroni podaci.
Za one koji traže veći nivo složenosti, tajmeri se mogu kombinovati sa Promises i async/await naredbama . Ovo omogućava kreiranje mnogo čitljivijih i profesionalnijih sekvenci čekanja, izbjegavajući zloglasni "pakao povratnih poziva" i omogućavajući asinhrono i uredno upravljanje više tajmera.
Sposobnost upravljanja vremenom u JavaScriptu je fundamentalna za kreiranje dinamičkih interfejsa, od digitalnih satova i animacija do sistema za ponovni pokušaj povezivanja. Savladavanje funkcije `setTimeout`, njeno prepisivanje sa `clearTimeout` i razumijevanje kako ona interaguje sa petljom događaja omogućava vam da optimizujete performanse aplikacije i poboljšate iskustvo krajnjeg korisnika, uvijek imajući na umu da tačnost vremena uveliko zavisi od okruženja i opterećenja sistema.