Callback funksiyalar

~15 daq · JavaScript · Funksiyalar chuqurroq

Muammodan boshlaylik

Server dan ma'lumot olish kerak. Lekin server javob berishi uchun vaqt kerak — 1 sekund, 2 sekund. Bu vaqtda dastur to'xtab turishi kerakmi?

Yo'q. Dastur ishlashda davom etadi — server javob berganda "mana, ma'lumot keldi, endi shu funksiyani chaqir" deyiladi. Bu funksiya — callback.


Callback nima?

Callback — boshqa funksiyaga parametr sifatida beriladigan funksiya. "Ish tugagach meni chaqir" — shu ma'noda.

function bajar(fn) {
  console.log("Ish boshlandi");
  fn(); // ← callback chaqiriladi
  console.log("Ish tugadi");
}

bajar(() => console.log("Men callback!")); 
// "Ish boshlandi"
// "Men callback!"
// "Ish tugadi"

Hayotiy o'xshatma

Restoranda ovqat buyurtma qildingiz. Ofitsiantga raqamingizni qoldirdingiz — "ovqat tayyor bo'lganda qo'ng'iroq qiling". Siz kutib o'tirmaysiz — boshqa ish qilasiz. Ovqat tayyor bo'lganda ofitsiant qo'ng'iroq qiladi.

Ofitsiantning qo'ng'iroq qilishi — callback. Siz raqamingizni (funksiyani) berdingiz, u kerakli vaqtda chaqirdi.


Sinxron callback

Ba'zi callbacklar darhol chaqiriladi — asinxron emas:

const sonlar = [3, 1, 4, 1, 5, 9];

// sort — callback darhol, sinxron chaqiriladi
sonlar.sort((a, b) => a - b); // [1, 1, 3, 4, 5, 9]

// forEach — sinxron
sonlar.forEach(n => console.log(n));

Asinxron callback

Asinxron callbacklar — keyinroq chaqiriladi:

console.log("1");

setTimeout(() => {
  console.log("2"); // ← 1 sekund keyin chaqiriladi
}, 1000);

console.log("3");

// Natija: "1", "3", "2"

setTimeout — "N millisekund keyin shu funksiyani chaqir" deydi. Dastur to'xtamaydi — "3" darhol chiqadi.

Hodisa (event) callback

const tugma = document.querySelector("#tugma");

tugma.addEventListener("click", function(event) {
  // ← foydalanuvchi bosganda chaqiriladi
  console.log("Bosildi!", event.target);
});

Foydalanuvchi qachon bosishini bilmaymiz — callback tayyor turadi.


Nima uchun shunday?

Nima uchun callback kerak?

JavaScript — bir oqimli (single-threaded). Bir vaqtda faqat bitta ish bajaradi. Server javobini kutib tursa — sahifa muzlab qoladi, foydalanuvchi hech narsa qila olmaydi.

Callback — "ish tugagach xabar ber" mexanizmi. Dastur boshqa ishlarni qilishda davom etadi.


Error-first callback — Node.js uslubi

Node.js da keng tarqalgan pattern: callbackning birinchi parametri — xato, ikkinchisi — natija.

const fs = require("fs");

fs.readFile("fayl.txt", "utf8", function(xato, mazmun) {
  if (xato) {
    console.error("Xato:", xato.message);
    return; // ← xato bo'lsa davom etmaymiz
  }
  console.log(mazmun); // ← xato yo'q, mazmun bor
});

Nima uchun xato birinchi? Xatoni tekshirishni unutmaslik uchun. Birinchi parametr bo'lsa — ko'zga tashlanadi.


Callback Hell — muammo

Bir nechta asinxron amal ketma-ket bajarilishi kerak bo'lsa — callbacklar ichma-ich bo'lib ketadi:

foydalanuvchiniOl(id, function(xato, foydalanuvchi) {
  if (xato) return console.error(xato);

  buyurtmalarniOl(foydalanuvchi.id, function(xato, buyurtmalar) {
    if (xato) return console.error(xato);

    mahsulotlarniOl(buyurtmalar[0].id, function(xato, mahsulotlar) {
      if (xato) return console.error(xato);

      // yana chuqurroq...
    });
  });
});

Bu — "Callback Hell" yoki "Pyramid of Doom". O'qish, xatolarni boshqarish, o'zgartirish qiyin. Bu muammoni Promise hal qiladi — keyingi darslarda.


Tez-tez uchraydigan xatolar

Callbackni chaqirish o'rniga uzatish:

setTimeout(console.log("Salom"), 1000); // ❌ darhol chaqiriladi!
setTimeout(() => console.log("Salom"), 1000); // ✅ 1 sekund keyin

Xatoni tekshirmaslik:

fs.readFile("fayl.txt", "utf8", function(xato, mazmun) {
  console.log(mazmun); // ❌ xato bo'lsa mazmun undefined
});

fs.readFile("fayl.txt", "utf8", function(xato, mazmun) {
  if (xato) return console.error(xato); // ✅
  console.log(mazmun);
});

Callbackni bir necha marta chaqirish:

function bajar(callback) {
  callback("natija");
  callback("yana"); // ❌ ikki marta chaqirildi!
}
// Callback bir marta chaqirilishi kerak

Xulosa

Callback — boshqa funksiyaga parametr sifatida beriladigan funksiya. "Ish tugagach meni chaqir."

Sinxron callback — darhol chaqiriladi (forEach, sort). Asinxron callback — keyinroq chaqiriladi (setTimeout, addEventListener, fs.readFile).

Node.js da error-first pattern: birinchi parametr xato, ikkinchisi natija.

Ko'p asinxron amallar ketma-ket bo'lsa — Callback Hell. Yechim: Promise va async/await.


Keyingi dars

14-dars: Pure funksiyalar va Side Effects