JavaScript'te Asenkron Programlama: Callbacks, Promises ve Async/Await’in Derinliklerine Yolculuk

JavaScript'te Asenkron Programlama: Callbacks, Promises ve Async/Await’in Derinliklerine Yolculuk

Bu blog yazısında, JavaScript'teki asenkron programlama yapıları olan Callback, Promise ve Async/Await hakkında derinlemesine bir inceleme yapıldı. Her bir yapının avantajları, dezavantajları ve gerçek dünya senaryolarında nasıl kullanılabileceği ele alın

BFS

Asenkron Programlamaya Giriş



JavaScript ile çalışırken, bir web sayfasının yüklenmesi veya bir API'den veri almak gibi işlemler, genellikle zaman alıcı olabilir. Bu tür işlemler, uygulamanın yanıt vermemesine yol açabilir. Peki, bir işlemin tamamlanmasını beklerken, kullanıcıların sayfanın diğer kısımlarını kullanabilmesini nasıl sağlarız?

İşte asenkron programlama burada devreye girer. Asenkron programlama, uzun süren işlemleri beklerken uygulamanın geri kalanı üzerinde işlem yapmaya devam etmemize olanak tanır. JavaScript'in asenkron yapısı sayesinde, bloklama olmadan verimli bir şekilde çalışabiliriz. Bu, özellikle büyük projelerde performans artışı ve kullanıcı deneyimi açısından büyük bir fark yaratır.

Callbacks ile Başlayan Yolculuk



Asenkron programlamaya ilk adım, callback fonksiyonları ile atılır. Callback’ler, bir fonksiyonun tamamlanmasının ardından çalışması için başka bir fonksiyonu parametre olarak alır. Bu yapı, ilk başta oldukça kullanışlı görünebilir. Ancak, işler karmaşıklaştıkça callback hell (callback cehennemi) adı verilen bir soruna yol açabilir.

Callback hell, iç içe geçmiş birçok callback fonksiyonunun kodu okunmaz hale getirmesiyle ortaya çıkar. Hangi işlemin hangi sırayla gerçekleştiğini takip etmek zorlaşır. Bu durum, kodun bakımını ve hata ayıklamasını oldukça güçleştirir. Gelin, callback fonksiyonlarının nasıl çalıştığını ve karşılaşılan sorunları biraz daha yakından inceleyelim:


function fetchData(callback) {
  setTimeout(function() {
    callback('Veri alındı');
  }, 1000);
}

fetchData(function(result) {
  console.log(result);
});


Yukarıdaki örnekte, `fetchData` fonksiyonu bir callback alır ve veriyi aldıktan sonra onu callback fonksiyonuna gönderir. Ancak, bu tür yapılar, karmaşık hale geldikçe, okunabilirliği zorlaştırabilir.

Promises: Callback Hell’den Kurtuluş



İşte burada Promises devreye girer. Promise, bir işlemin başarıyla tamamlanıp tamamlanmadığını veya bir hata ile karşılaşıp karşılaşmadığını bildirir. Promises, callback hell sorununu ortadan kaldırarak daha temiz ve anlaşılır kodlar yazmamıza yardımcı olur.

Promises, üç ana duruma sahip olabilir:

1. Pending (Beklemede): Promise henüz tamamlanmamış ve sonuç bekleniyor.
2. Resolved (Çözülmüş): Promise başarılı bir şekilde tamamlanmış ve sonucu elde edilmiş.
3. Rejected (Reddedilmiş): Promise bir hata nedeniyle başarısız olmuş.

Örnek bir Promise kullanımı şu şekilde olabilir:


function fetchData() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      const success = true;
      if (success) {
        resolve('Veri alındı');
      } else {
        reject('Hata oluştu');
      }
    }, 1000);
  });
}

fetchData()
  .then(function(result) {
    console.log(result);
  })
  .catch(function(error) {
    console.log(error);
  });


Bu yapıyla, hem başarılı sonuçları `.then()` metodu ile hem de hataları `.catch()` metodu ile kolayca yönetebilirsiniz. Promises, callback hell problemini büyük ölçüde çözer ve kodunuzu daha okunabilir hale getirir.

Async/Await: Modern JavaScript’te Temiz ve Okunabilir Kod



Asenkron programlamanın bir sonraki büyük adımı, async/await yapısıdır. Bu yapı, Promises’ın kullanımını daha da kolaylaştırır ve kodunuzu daha temiz hale getirir. Özellikle büyük projelerde, asenkron işlemleri yönetmek için async/await kombinasyonu son derece etkili bir çözüm sunar.

Bir `async` fonksiyon, her zaman bir Promise döner. İçindeki `await` anahtar kelimesi ise, bir Promise’in çözülmesini beklerken, kodun geri kalanını engellemeden işlem yapmaya devam etmemizi sağlar.

Aşağıda, async/await kullanarak asenkron bir işlemi nasıl daha okunabilir hale getirebileceğimizi gösterelim:


async function fetchData() {
  const result = await new Promise(function(resolve, reject) {
    setTimeout(function() {
      const success = true;
      if (success) {
        resolve('Veri alındı');
      } else {
        reject('Hata oluştu');
      }
    }, 1000);
  });
  console.log(result);
}

fetchData();


Görüldüğü gibi, `await` anahtar kelimesi, Promises ile çalışırken daha temiz bir yapı oluşturur. Kodun okunabilirliği artar ve asenkron işlemler daha düzenli bir şekilde yönetilebilir.

Performans İyileştirmeleri ve Hata Yönetimi



Asenkron programlama, doğru kullanıldığında uygulamanın performansını artırabilir. Ancak, bu yapıların yanlış kullanımı, beklenmedik hatalara ve performans sorunlarına yol açabilir. Asenkron kod yazarken dikkat edilmesi gereken en önemli noktalardan biri, hata yönetimidir. Asenkron işlemlerde karşılaşılan hataları düzgün bir şekilde yakalamak, uygulamanın güvenilirliğini artırır.

Performans iyileştirmeleri yaparken, özellikle gereksiz işlemleri engellemek ve paralel çalışan işlemleri doğru şekilde yönetmek çok önemlidir.

Gerçek Dünya Uygulamaları



Asenkron yapılar, sadece öğrenmek için değil, gerçek dünya projelerinde de sıkça kullanılır. Örneğin, bir API'den veri çekmek için asenkron kod kullanmak yaygın bir senaryodur. API çağrıları genellikle zaman alıcıdır ve kullanıcı deneyimini olumsuz etkileyebilir. Asenkron yapılar, bu işlemleri arka planda yaparak kullanıcıların diğer işlemleri gerçekleştirmelerine imkan tanır.


async function getWeatherData(city) {
  const response = await fetch(`https://api.weather.com/${city}`);
  const data = await response.json();
  console.log(data);
}

getWeatherData('İstanbul');


Yukarıdaki örnek, bir hava durumu API’sinden veri çekmek için asenkron yapıları kullanıyor. Kullanıcılar, hava durumu verisi yüklenene kadar diğer işlemleri yapmaya devam edebilirler.

İlgili Yazılar

Benzer konularda diğer yazılarımız

Modern Yazılım Geliştirme Süreçlerinde Yapay Zeka ve Otomasyonun Rolü: 2025’te Yeni Başlangıçlar

Yazılım geliştirme dünyası hızla evriliyor. 2025 yılına adım attığımızda, bu süreçte yapay zeka ve otomasyonun rolü hiç olmadığı kadar önemli hale geldi. Geçmişte yazılım geliştirme yalnızca kod yazmak ve sistemleri test etmekle sınırlıydı. Ancak bugünün...

Yazılım Geliştiriciler İçin Verimli Çalışma Alanı Oluşturmanın İpuçları: En İyi Araçlar ve Yöntemler

Verimli Bir Çalışma Alanı Neden Önemlidir?Yazılım geliştirici olmanın zorluklarından biri de sürekli odaklanmış ve üretken olabilmektir. Bir geliştirici olarak, işlerinizin çoğunu bilgisayar başında geçirirsiniz ve bu süre zarfında verimli bir çalışma...

Kodunuzu Temiz Tutun: Yazılımda 'Yavaş Kodu' Tespit Etmenin 7 Etkili Yolu

Yazılım geliştirme dünyasında zamanın ne kadar kıymetli olduğunu hepimiz biliyoruz. Yazdığınız kodun hızlı ve verimli olması, projelerinizi başarılı kılmanın anahtarıdır. Ama ne yazık ki, çoğu zaman kodu hızlı yazmak uğruna temizliği ihmal edebiliriz....