Timers moduli


ULASHISH

Taymerlar moduli nima?

Taymerlar moduli ma’lum vaqt yoki vaqt oralig‘ida kod bajarilishini rejalashtirishga yordam beradigan funksiyalarni taqdim etadi.

JavaScript brauzeridan farqli o‘laroq, Node.js vaqtni belgilash funksiyalari Taymerlar modulining bir qismi sifatida taqdim etilgan, ammo ular aniq importni talab qilmasdan butun dunyoda mavjud.

Asosiy xususiyatlarga quyidagilar kiradi:

  • setTimeout() bilan kechiktirilgan ijro
  • setInterval() bilan takroriy bajarish
  • setImmediate() bilan keyingi voqealar siklida darhol bajarish
  • Zamonaviy async/await naqshlari uchun Promise-ga asoslangan API

Ushbu qobiliyatlar sezgir ilovalarni yaratish, so‘rovni amalga oshirish, kechiktirilgan operatsiyalarni boshqarish va boshqalar uchun zarurdir.


Taymerlar bilan ishlashni boshlash

Kodning bajarilishini rejalashtirish uchun Taymerlar modulidan foydalanishning tezkor misoli:

Taymerning asosiy namunasi

const { setTimeout, setInterval, setImmediate } = require('timers');

console.log('Starting timers...');

// Execute once after delay
setTimeout(() => {
  console.log('This runs after 1 second');
}, 1000);

// Execute repeatedly at interval
let counter = 0;
const interval = setInterval(() => {
  counter++;
  console.log(`Interval tick ${counter}`);
  if (counter >= 3) clearInterval(interval);
}, 1000);

// Execute in the next event loop iteration
setImmediate(() => {
  console.log('This runs in the next iteration of the event loop');
});

console.log('Timers scheduled');
Misolni ishga tushirish »

Taymerlar modulidan foydalanish

Taymerlar modulining funksiyalari butun dunyo bo‘ylab mavjud, shuning uchun ularni aniq talab qilishingiz shart emas.

Biroq, ilg‘or xususiyatlarga kirishni istasangiz yoki aniqlik uchun modulni import qilishingiz mumkin:

const timers = require('timers');

// Or, for the promises API (Node.js 15.0.0+)
const timersPromises = require('timers/promises');

setTimeout() va clearTimeout()

setTimeout() funksiyasi callback’ni ko‘rsatilgan vaqtdan (millisekundlarda) keyin bajarishni rejalashtiradi.

Vaqt tugashini bekor qilish uchun ishlatilishi mumkin bo‘lgan Timeout obyektini qaytaradi.

Umumiy foydalanish holatlari

  • Muhim bo‘lmagan vazifalarni bajarishni kechiktirish
  • Operatsiyalar uchun taym-autlarni amalga oshirish
  • Protsessor talab qiladigan vazifalarni ajratish
  • Qayta urinish mantiqini amalga oshirish
// Basic usage
setTimeout(() => {
  console.log('This message is displayed after 2 seconds');
}, 2000);

// With arguments
setTimeout((name) => {
  console.log(`Hello, ${name}!`);
}, 1000, 'World');

// Storing and clearing a timeout
const timeoutId = setTimeout(() => {
  console.log('This will never be displayed');
}, 5000);

// Cancel the timeout before it executes
clearTimeout(timeoutId);
console.log('Timeout has been cancelled');
Misolni ishga tushirish »

Promise-ga asoslangan setTimeout

Node.js 15.0.0 va undan keyingi versiyalari taymerlar uchun Promiselarga asoslangan API taqdim etadi:

const { setTimeout } = require('timers/promises');

async function delayedGreeting() {
  console.log('Starting...');

  // Wait for 2 seconds
  await setTimeout(2000);

  console.log('After 2 seconds');

  // Wait for 1 second with a value
  const result = await setTimeout(1000, 'Hello, World!');

  console.log('After 1 more second:', result);
}

delayedGreeting().catch(console.error);
Misolni ishga tushirish »


setInterval() va clearInterval()

setInterval() funksiyasi funksiyani belgilangan oraliqlarda (millisekundlarda) qayta-qayta chaqiradi.

U intervalni to‘xtatish uchun ishlatilishi mumkin bo‘lgan Interval obyektini qaytaradi.

Umumiy foydalanish holatlari

  • Yangilanishlar uchun so‘rov
  • Davriy texnik xizmat ko‘rsatish vazifalarini bajarish
  • Yurak urishi mexanizmlarini amalga oshirish
  • UI elementlarini muntazam ravishda yangilash

Eslatma: Agar voqealar sikli boshqa operatsiyalar tomonidan bloklangan bo‘lsa, bajarilishlar orasidagi haqiqiy interval belgilangandan uzoqroq bo‘lishi mumkin.

// Basic interval
let counter = 0;
const intervalId = setInterval(() => {
  counter++;
  console.log(`Interval executed ${counter} times`);

  // Stop after 5 executions
  if (counter >= 5) {
    clearInterval(intervalId);
    console.log('Interval stopped');
  }
}, 1000);

// Interval with arguments
const nameInterval = setInterval((name) => {
  console.log(`Hello, ${name}!`);
}, 2000, 'Node.js');

// Stop the name interval after 6 seconds
setTimeout(() => {
  clearInterval(nameInterval);
  console.log('Name interval stopped');
}, 6000);
Misolni ishga tushirish »

Promise-ga asoslangan to‘plamInterval

Intervallar uchun Promiselar API dan foydalanish:

const { setInterval } = require('timers/promises');

async function repeatedGreeting() {
  console.log('Starting interval...');

  // Create an async iterator from setInterval
  const interval = setInterval(1000, 'tick');

  // Limit to 5 iterations
  let counter = 0;

  for await (const tick of interval) {
    console.log(counter + 1, tick);
    counter++;

    if (counter >= 5) {
      break; // Exit the loop, stopping the interval
    }
  }

  console.log('Interval finished');
}

repeatedGreeting().catch(console.error);
Misolni ishga tushirish »

setImmediate() va clearImmediate()

setImmediate() funksiyasi callback funksiyasini voqealar siklining keyingi iteratsiyasida, kiritish/chiqarish hodisalaridan keyin, lekin taymerlardan oldin bajarish uchun rejalashtiradi.

Bu setTimeout(callback, 0) dan foydalanishga o‘xshaydi, ammo samaraliroq.

setImmediate() qachon ishlatiladi

  • Joriy operatsiya tugagandan so‘ng kodni bajarmoqchi bo‘lganingizda
  • Uzoq muddatli operatsiyalarni kichikroq bo‘laklarga bo‘lish uchun
  • I/U operatsiyalari tugagandan so‘ng callback funksiyasilar bajarilishini ta’minlash uchun
  • Stack to‘lib ketishining oldini olish uchun rekursiv funksiyalarda
console.log('Start');

setTimeout(() => {
  console.log('setTimeout callback');
}, 0);

setImmediate(() => {
  console.log('setImmediate callback');
});

process.nextTick(() => {
  console.log('nextTick callback');
});

console.log('End');
Misolni ishga tushirish »

Amalga oshirish tartibi odatda quyidagicha bo‘ladi:

  1. Boshlash
  2. Oxiri
  3. callback-ni keyingi belgilang
  4. setTimeout callback’i yoki setImmediate callback’i (tartib o‘zgarishi mumkin)

Eslatma: setTimeout(0) va setImmediate() o‘rtasidagi bajarilish tartibi asosiy moduldan chaqirilganda oldindan aytib bo‘lmaydigan bo‘lishi mumkin.

Biroq, kiritish/chiqarish qo‘ng‘irog‘i ichida setImmediate() har doim taymerlardan oldin bajariladi.

Darhol bekor qilish

const immediateId = setImmediate(() => {
  console.log('This will not be displayed');
});

clearImmediate(immediateId);
console.log('Immediate has been cancelled');
Misolni ishga tushirish »

process.nextTick()

Taymerlar modulining bir qismi bo‘lmasa-da, process.nextTick() tegishli funksiya bo‘lib, u callback funksiyasini voqealar siklining keyingi iteratsiyasigacha kechiktiradi, lekin uni har qanday kiritish/chiqarish hodisalari yoki taymerlar oldidan bajaradi.

Asosiy xususiyatlar

  • Har qanday kiritish-chiqarish hodisalari yoki taymerlardan oldin ishlaydi
  • setImmediate() dan yuqoriroq ustuvorlik
  • Hodisa davri davom etgunga qadar barcha navbatda turgan callback funksiyasilarni qayta ishlaydi
  • Haddan tashqari ishlatilsa, I/O ochlikka olib kelishi mumkin

process.nextTick() qachon ishlatiladi

  • Callback joriy operatsiyadan keyin, lekin har qanday kiritish/chiqarishdan oldin bajarilishini ta’minlash uchun
  • Uzoq muddatli operatsiyalarni buzish uchun
  • Obyekt yaratilgandan so‘ng hodisa ishlov beruvchilarini sozlashga ruxsat berish
  • APIning izchil harakatini ta’minlash uchun (masalan, konstruktorlarni "yangi" bilan yoki ularsiz ishlashini ta’minlash)
console.log('Start');

// Schedule three different types of callbacks
setTimeout(() => {
  console.log('setTimeout executed');
}, 0);

setImmediate(() => {
  console.log('setImmediate executed');
});

process.nextTick(() => {
  console.log('nextTick executed');
});

console.log('End');
Misolni ishga tushirish »

Eslatma: process.nextTick() event loop’ning (hodisalar sikli) joriy bosqichida darhol ishga tushadi, setImmediate() esa event loop’ning keyingi iteratsiyasida, ya’ni keyingi “tick”da ishga tushadi.


Kengaytirilgan taymer naqshlari

O‘chirish

Funksiyani bajarishni kechiktirish orqali uni juda tez-tez chaqirishning oldini oling:

function debounce(func, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}
// Example usage
const handleResize = debounce(() => {
  console.log('Window resized');
}, 300);
// Call handleResize() on window resize

Bostirish

Vaqt o‘tishi bilan funksiya qanchalik tez-tez chaqirilishini cheklang:

function throttle(func, limit) {
  let inThrottle = false;
  return function(...args) {
    if (!inThrottle) {
      func.apply(this, args);
      inThrottle = true;
      setTimeout(() => inThrottle = false, limit);
    }
  };
}
// Example usage
const handleScroll = throttle(() => {
  console.log('Handling scroll');
}, 200);
// Call handleScroll() on window scroll

Ketma-ket kutish vaqti

Ular orasidagi kechikishlar bilan bir qator operatsiyalarni bajaring:

function sequentialTimeouts(callbacks, delay = 1000) {
  let index = 0;
  function next() {
    if (index < callbacks.length) {
      callbacks[index]();
      index++;
      setTimeout(next, delay);
    }
  }
  next();
}
// Example usage
sequentialTimeouts([
  () => console.log('Step 1'),
  () => console.log('Step 2'),
  () => console.log('Step 3')
], 1000);

Taymer harakati va eng yaxshi amaliyotlar

Taymerning aniqligi va ishlashi

Node.js taymerlari millisekundgacha aniq emas. Haqiqiy kechikish quyidagi sabablarga ko‘ra biroz uzoqroq bo‘lishi mumkin:

  • Tizim yuki va protsessordan foydalanish
  • Hodisa siklini blokirovka qilish operatsiyalari
  • Boshqa taymerlar va kiritish-chiqarish operatsiyalari
  • System timer resolution (typically 1-15ms)

Taymerning aniqligini o‘lchash

const desiredDelay = 100; // 100ms
const start = Date.now();

setTimeout(() => {
  const actualDelay = Date.now() - start;
  console.log(`Desired delay: ${desiredDelay}ms`);
  console.log(`Actual delay: ${actualDelay}ms`);
  console.log(`Difference: ${actualDelay - desiredDelay}ms`);
}, desiredDelay);

Xotira va resurslarni boshqarish

Taymerlarni to‘g‘ri boshqarish xotiraning oqishi va ortiqcha resurslardan foydalanishning oldini olish uchun juda muhimdir:

Umumiy xotira o‘qish naqshlari

// Leak: Interval keeps running even if not needed
function startService() {
  setInterval(() => {
    fetchData();
  }, 1000);
}
// Leak: Timeout with closure over large object
function processData(data) {
  setTimeout(() => {
    console.log('Processing complete');
   // 'data' is kept in memory until the timeout fires
  }, 10000, data);
}

Eng yaxshi amaliyotlar

  • Har doim kerak bo‘lmaganda intervallarni va taym-autlarni tozalang
  • Taymer identifikatorlarini tozalash imkonini beradigan tarzda saqlang
  • Taymer callback funksiyalarida closures (yopiq funksiyalar) bilan ehtiyot bo‘ling
  • Tozalash funksiyalarida clearTimeout() va clearInterval() dan foydalaning

Taymerlar kerak bo‘lmaganda, ayniqsa uzoq vaqt ishlaydigan ilovalarda, xotira oqishini oldini olish uchun tozalashni unutmang:

// Bad practice in a server context
function startServer() {
  setInterval(() => {
    // This interval will run forever and prevent proper cleanup
    console.log('Server is running...');
  }, 60000);
}

// Better practice
function startServer() {
  const intervalId = setInterval(() => {
    console.log('Server is running...');
  }, 60000);

  // Store the interval ID for later cleanup
  return {
    stop: () => {
      clearInterval(intervalId);
      console.log('Server stopped');
    }
  };
}

// Example usage
const server = startServer();

// Stop the server after 3 minutes
setTimeout(() => {
  server.stop();
}, 180000);

Nolinchi kechikish vaqti

setTimeout(callback, 0) dan foydalanilganda, callback funksiyasi darhol amalga oshirilmaydi.

U protsessorni ko‘p talab qiladigan vazifalarni "parchalash" uchun ishlatilishi mumkin bo‘lgan joriy voqealar sikli sikli tugagandan so‘ng amalga oshiriladi:

function processArray(array, processFunction) {
  const chunkSize = 1000;
  let index = 0;

  function processChunk() {
    const chunk = array.slice(index, index + chunkSize);
    chunk.forEach(processFunction);

    index += chunkSize;

    if (index < array.length) {
      setTimeout(processChunk, 0); // Yield to the event loop
    } else {
      console.log('Processing complete');
    }
  }

  processChunk();
}

// Example usage
const bigArray = Array(10000).fill().map((_, i) => i);

console.log('Starting processing...');
processArray(bigArray, (item) => {
  // Simple processing
  if (item % 5000 === 0) {
    console.log(`Processed item ${item}`);
  }
});
console.log('This will log before processing completes');
Misolni ishga tushirish »


W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!