Tüm blog yazıları

Callback Hell: İç İçe Geçmiş Callback'lerin Kabusu

JavaScript asenkron yapısında callback'ler önemlidir. Ancak iç içe geçmiş kullanımlar, kodunuzu bir kabusa çeviren 'Callback Hell' sorununa yol açar. Bu yazıda, bu yaygın problemi ve kodun nasıl okunaksız hale geldiğini inceliyor, neden daha iyi çözüm yaklaşımlarına ihtiyacımız olduğunu gösteriyoruz

eminbasbayan4 dk okuma
Callback Hell: JavaScript'teki İç İçe Callback Kabusu

Önceki makalelerde JavaScript'in asenkron yapısını ve callback fonksiyonlarını öğrendik. Ancak callback'ler bir noktadan sonra kontrol edilemez hale gelebilir. Bu duruma geliştiriciler arasında "Callback Hell" (Callback Cehennemi) denir. Bu makalede bu problemi anlayacak ve neden daha iyi çözümlere ihtiyacımız olduğunu göreceğiz.

Callback Nedir? (Hızlı Tekrar)

Callback, başka bir fonksiyona parametre olarak geçirilen ve daha sonra çağrılacak olan fonksiyondur:

javascript
function islemYap(callback) {
    // Bir şeyler yap...
    callback(); // Sonra bu fonksiyonu çağır
}

islemYap(function() {
    console.log("İşlem tamamlandı!");
});

Problem: Sıralı Asenkron İşlemler

Diyelim ki bir renk değiştirme animasyonu yapmak istiyorsunuz. Her renk 1 saniye görünsün:

javascript
// İstenen: Kırmızı → Turuncu → Sarı → Yeşil → Mavi

İlk Deneme: Callback Olmadan

javascript
setTimeout(function() {
    document.body.style.backgroundColor = 'red';
}, 1000);

setTimeout(function() {
    document.body.style.backgroundColor = 'orange';
}, 1000);

setTimeout(function() {
    document.body.style.backgroundColor = 'yellow';
}, 1000);

Problem: Hepsi aynı anda (1 saniye sonra) çalışır! Sadece sarıyı görürüz.

İkinci Deneme: Süreleri Toplama

javascript
setTimeout(function() {
    document.body.style.backgroundColor = 'red';
}, 1000);

setTimeout(function() {
    document.body.style.backgroundColor = 'orange';
}, 2000); // 1 + 1

setTimeout(function() {
    document.body.style.backgroundColor = 'yellow';
}, 3000); // 1 + 1 + 1

Bu çalışır ama kırılgan bir çözüm:

  • Süreleri elle hesaplıyoruz
  • Bir süreyi değiştirmek istesek, hepsini güncellememiz gerekir
  • Mantıksal olarak bağlantısız görünüyor

Üçüncü Deneme: İç İçe Callback'ler

javascript
setTimeout(function() {
    document.body.style.backgroundColor = 'red';
    
    setTimeout(function() {
        document.body.style.backgroundColor = 'orange';
        
        setTimeout(function() {
            document.body.style.backgroundColor = 'yellow';
            
            setTimeout(function() {
                document.body.style.backgroundColor = 'green';
                
                setTimeout(function() {
                    document.body.style.backgroundColor = 'blue';
                    
                }, 1000);
            }, 1000);
        }, 1000);
    }, 1000);
}, 1000);

Bu çalışır ama... 😱

Callback Hell'e Hoş Geldiniz

Yukarıdaki koda bakın. Gördüğünüz şey Callback Hell:

metin
                                    ┐
                                ┐   │
                            ┐   │   │
                        ┐   │   │   │
                    ┐   │   │   │   │
                ┐   │   │   │   │   │
            }); │   │   │   │   │   │
        });     │   │   │   │   │   │
    });         │   │   │   │   │   │
});             │   │   │   │   │   │
                └───┴───┴───┴───┴───┘
                    "Piramit of Doom"

Gerçek Hayat Örneği: Kullanıcı Kayıt Süreci

Bir kullanıcı kayıt işlemi düşünün:

  1. E-posta'nın kullanılıp kullanılmadığını kontrol et
  2. Şifreyi hashle
  3. Kullanıcıyı veritabanına kaydet
  4. Hoş geldin e-postası gönder
  5. Kullanıcıyı giriş yap

Her adım asenkron ve bir öncekine bağlı:

javascript
emailKontrol(email, function(emailMevcut) {
    if (emailMevcut) {
        hataGoster("Bu e-posta zaten kayıtlı");
    } else {
        sifreHashle(sifre, function(hashliSifre) {
            kullaniciKaydet(email, hashliSifre, function(kullanici) {
                hosgeldinEmailiGonder(email, function(emailSonuc) {
                    if (emailSonuc.basarili) {
                        kullaniciyiGirisYap(kullanici, function(oturum) {
                            anaSayfayaYonlendir();
                        }, function(hata) {
                            hataGoster("Giriş yapılamadı: " + hata);
                        });
                    } else {
                        hataGoster("E-posta gönderilemedi");
                    }
                }, function(hata) {
                    hataGoster("E-posta gönderilemedi: " + hata);
                });
            }, function(hata) {
                hataGoster("Kayıt başarısız: " + hata);
            });
        }, function(hata) {
            hataGoster("Şifre işlenemedi: " + hata);
        });
    }
}, function(hata) {
    hataGoster("E-posta kontrol edilemedi: " + hata);
});

Bu kod:

  • ❌ Okunması çok zor
  • ❌ Hata yönetimi karmaşık
  • ❌ Debug etmek kabus
  • ❌ Bakımı imkansız

Neden Bu Kadar Kötü?

1. Okunabilirlik Sıfır

Kod sağa doğru kayarak "piramit" oluşturuyor. Hangi kapanış parantezi hangi açılışa ait anlamak imkansız.

2. Hata Yönetimi Dağınık

Her callback için ayrı hata callback'i gerekiyor:

javascript
islemYap(
    function(sonuc) { /* başarılı */ },
    function(hata) { /* başarısız */ }
);

3. Değişiklik Yapmak Zor

Bir adım eklemek veya çıkarmak istediğinizde, tüm iç içe yapıyı değiştirmeniz gerekiyor.

4. Hata Ayıklama Kabusu

Hangi satırda hata var? Hangi callback çalışmadı? Stack trace okumak imkansız hale geliyor.

Callback Hell'den Kaçış Yolları

Yol 1: Fonksiyonları Ayırma

javascript
function emailKontrolEt() {
    emailKontrol(email, sifreIsle, hataYakala);
}

function sifreIsle(emailMevcut) {
    if (emailMevcut) {
        hataGoster("E-posta zaten kayıtlı");
        return;
    }
    sifreHashle(sifre, kullaniciOlustur, hataYakala);
}

function kullaniciOlustur(hashliSifre) {
    kullaniciKaydet(email, hashliSifre, emailGonder, hataYakala);
}

// ... devam eder

Bu biraz daha iyi ama hala ideal değil.

Yol 2: Named Functions (İsimli Fonksiyonlar)

javascript
setTimeout(kirmiziYap, 1000);

function kirmiziYap() {
    document.body.style.backgroundColor = 'red';
    setTimeout(turuncuYap, 1000);
}

function turuncuYap() {
    document.body.style.backgroundColor = 'orange';
    setTimeout(sariYap, 1000);
}

function sariYap() {
    document.body.style.backgroundColor = 'yellow';
    // ... devam eder
}

Daha okunabilir ama hala bağımlılıklar karışık.

Yol 3: Promises (Söz Nesneleri) ⭐

İşte gerçek çözüm! Bir sonraki makalenin konusu:

javascript
// Callback Hell yerine:
renkDegistir('red', 1000)
    .then(() => renkDegistir('orange', 1000))
    .then(() => renkDegistir('yellow', 1000))
    .then(() => renkDegistir('green', 1000))
    .then(() => renkDegistir('blue', 1000))
    .catch(hata => console.log("Bir şeyler yanlış gitti!"));

Düz, okunabilir ve tek hata yakalama noktası!

Özet

Bu makalede öğrendiklerimiz:

✅ Callback Hell, iç içe geçmiş callback'lerin oluşturduğu karmaşadır
✅ Sıralı asenkron işlemler callback'lerle çok zor yönetilir
✅ Kod okunabilirliği, bakımı ve hata yönetimi zorlaşır
✅ Fonksiyonları ayırmak geçici bir çözümdür
✅ Gerçek çözüm: Promises (bir sonraki makalemiz!)

Bir sonraki makalede JavaScript Promises konusunu derinlemesine inceleyeceğiz.

JavaScript Classes ile pratik uygulamalar, metotlar arası iletişim ve gerçek dünya kod örnekleri
JavaScript Dersleri9 dk okuma

JavaScript Classes - Pratik Uygulamalar

JavaScript class'ları ile pratik uygulamalara geçin! Metotlar arası iletişimden constructor'da metot çağırmaya, kod tekrarını azaltmaktan gerçek dünya senaryolarına kadar class kullanımının inceliklerini keşfedin. Kendi alışveriş sepeti örneğinizle bilginizi pekiştirin.

Yazıyı oku
JavaScript class yapısını gösteren bir kod örneği, ES6 ile modern nesne oluşturma
JavaScript Dersleri9 dk okuma

JavaScript Classes

ES6 ile JavaScript'e gelen class yapısı sayesinde nesne oluşturmak artık çok daha kolay ve düzenli! Constructor function karmaşasından kurtulup, okunabilir ve yönetilebilir kodlar yazmak isteyenler için modern JavaScript'in temel taşı olan class'ları tüm detaylarıyla keşfedin. Bu rehberle nesne şabl

Yazıyı oku
JavaScript kodunda Constructor Function ve new keyword'ü ile nesne oluşturma örnekleri
JavaScript Dersleri8 dk okuma

Constructor Functions ve new Keyword

Factory Function'ların hafıza israfı sorununa Constructor Function'lar ve new keyword'ü ile son verin! Metotları paylaştırarak JavaScript objelerini daha verimli nasıl oluşturacağınızı, new'in perde arkasında neler yaptığını ve prototype sisteminin gücünü bu rehberde keşfedin.

Yazıyı oku

Çerez tercihlerin

Platformun çalışması için zorunlu çerezler kullanıyoruz. İzin verirsen anonim kullanım verilerini ölçüyoruz. Ayrıntıları incele