Funksiyalar bilan chuqur ishlash

setTimeout va setInterval

Ba'zan funksiyani darhol emas, balki ma'lum vaqtdan keyin yoki muntazam takror bajarish kerak bo'ladi. Buning uchun ikkita asosiy metod bor: setTimeout va setInterval. Bu metodlar spetsifikatsiyaning bir qismi emas, lekin brauzer ham, Node.js ham ularni qo'llab-quvvatlaydi.

Bu darsdagi ko'p misollar statik kod shaklida berilgan. Sabab: maydoncha (playground) faqat console.log/return natijasini darhol ko'rsatadi, setTimeout/setInterval esa natijani kechikish bilan chiqaradi โ€” u maydonchada ko'rinmaydi. Kodlarni brauzer konsolida sinab ko'ring.

setTimeout โ€” bir marta kechiktirish

setTimeout funksiyani berilgan vaqtdan (millisekundlarda) keyin bir marta bajaradi. Sintaksisi:

let timerId = setTimeout(func, delay, arg1, arg2, ...);
function salomBer() {
  console.log("Salom!");
}

// 2 soniyadan keyin "Salom!" chiqadi:
setTimeout(salomBer, 2000);

// Argumentlar bilan:
function xabar(kim, matn) {
  console.log(matn + ", " + kim);
}
setTimeout(xabar, 1000, "Ali", "Assalomu alaykum");
// 1 soniyadan keyin: Assalomu alaykum, Ali
Funksiyani chaqirmasdan uzating: setTimeout(salomBer, 1000) to'g'ri. Agar qavs bilan setTimeout(salomBer(), 1000) yozsangiz โ€” salomBer() darhol bajariladi va uning natijasi (odatda undefined) uzatiladi. Bu keng tarqalgan xato.

clearTimeout โ€” bekor qilish

setTimeout chaqirilganda "timer identifikatori"ni qaytaradi. Uni clearTimeoutga berib, rejalashtirilgan bajarishni bekor qilish mumkin:

let timerId = setTimeout(function() {
  console.log("Bu hech qachon chiqmaydi");
}, 2000);

clearTimeout(timerId); // taymerni bekor qildik
// funksiya ishga tushmaydi
Timerni bekor qilgandan keyin ham identifikator qiymati saqlanib qoladi โ€” u "tozalanmaydi", lekin qayta ishlatilmaydi. Bekor qilish faqat rejalashtirilgan bajarishni to'xtatadi.

setInterval โ€” takroran bajarish

setInterval sintaksisi setTimeout bilan bir xil, lekin farqi shundaki, funksiya bir marta emas, muntazam โ€” har delay millisekundda takror bajariladi:

// Har 2 soniyada bir marta xabar:
let timerId = setInterval(function() {
  console.log("tik");
}, 2000);

// 5 soniyadan keyin butun takrorlashni to'xtatish:
setTimeout(function() {
  clearInterval(timerId);
  console.log("to'xtatildi");
}, 5000);

// Natija (konsolda): tik, tik, to'xtatildi

clearInterval(timerId) โ€” takrorlashni to'xtatadi. Aks holda funksiya cheksiz takrorlanaveradi.

Ko'pchilik brauzerlarda tab (varaq) faol bo'lmaganda (fonda) setInterval ohangini sekinlashtiradi yoki to'xtatadi โ€” bu resurslarni tejash uchun. Aniq vaqtga tayanadigan hisob-kitoblarda buni yodda tuting.

Ichma-ich setTimeout

Muntazam bajarishning yana bir usuli โ€” setInterval o'rniga ichma-ich (nested) setTimeout. Funksiya har safar o'zi uchun keyingi setTimeoutni rejalashtiradi:

let timerId = setTimeout(function tick() {
  console.log("tik");
  timerId = setTimeout(tick, 2000); // o'zini qayta rejalashtiradi
}, 2000);

// Natija: har 2 soniyada "tik"

Ichma-ich setTimeout setIntervaldan quyidagi jihatlar bilan afzal:

  1. Kechikishni moslashuvchan boshqarish โ€” har bir chaqiruvdan keyin kechikishni o'zgartirish mumkin (masalan, serverda yuklama oshsa, so'rovlar oralig'ini kattalashtirish);
  2. Aniqroq oraliq kafolati โ€” keyingi chaqiruv oldingisi tugagach rejalashtiriladi, shuning uchun bajarishlar bir-birining ustiga chiqmaydi.
setIntervalda ichki kechikish funksiya bajarilish vaqtini o'z ichiga oladi. Agar funksiya uzoq ishlasa, real oraliq belgilangandan kichik bo'lishi (yoki chaqiruvlar navbatga to'planishi) mumkin. Ichma-ich setTimeout bu muammoni hal qiladi.

Nolinchi kechikish: setTimeout(func, 0)

Maxsus hol โ€” setTimeout(func, 0) yoki oddiy setTimeout(func). Bu funksiyani "iloji boricha tez", lekin joriy kod to'liq tugagandan keyin bajarishni rejalashtiradi.

console.log("Boshlanish");

setTimeout(function() {
  console.log("Kechikkan (0 ms)");
}, 0);

console.log("Tugash");

// Natija tartibi (konsolda):
// Boshlanish
// Tugash
// Kechikkan (0 ms)

"Kechikkan" xabari oxirida chiqadi โ€” chunki setTimeout funksiyani navbatga qo'yadi va u joriy skript to'liq bajarilib bo'lgach ishga tushadi. Bu "joriy kodni bloklamasdan, keyinroq bajarish" uchun ishlatiladigan usul.

Brauzerlarda ichma-ich setTimeout 5 martadan keyin minimal kechikishni ~4 ms ga majburiy oshiradi (HTML standarti talabi). Shuning uchun "0 ms" aslida bir necha millisekundga aylanishi mumkin. Node.js'da bu cheklov boshqacha.

Xulosa