JavaScript’te Asenkron Programlamaya Giriş: Callback, Promise ve Async/Await Arasındaki Farklar ve En İyi Kullanım Senaryoları

JavaScript’te Asenkron Programlamaya Giriş: Callback, Promise ve Async/Await Arasındaki Farklar ve En İyi Kullanım Senaryoları

Bu blog yazısında, JavaScript’te asenkron programlamanın temelleri, callback, promise ve async/await arasındaki farklar detaylıca ele alınmıştır. Kod parçacıkları ve örneklerle geliştiricilere rehberlik edilmektedir.

BFS

JavaScript dünyasında, asenkron programlama her geliştiricinin mutlaka öğrenmesi gereken bir konu. Bu temel kavram, kullanıcıların beklemesi gereken zamanları en verimli şekilde kullanmalarını sağlar ve uygulamanızın daha hızlı çalışmasına olanak tanır. Peki, asenkron programlama nedir ve en iyi nasıl kullanılır? Bu yazıda, asenkron programlamanın temellerine, Callback, Promise ve Async/Await yapılarına ve bu yapıların doğru kullanım senaryolarına göz atacağız.

Asenkron Programlama Nedir?



Asenkron programlama, bir işlemin tamamlanmasını beklemeden diğer işlemlerin devam etmesine imkan tanır. JavaScript gibi dillerde, kullanıcı etkileşimleri, veritabanı sorguları veya ağ istekleri gibi zaman alan işlemler sırasında, uygulamanızın diğer bölümleri çalışmaya devam edebilir. Yani, JavaScript'te asenkron kod yazmak, uygulamanızın "beklemesi" yerine diğer işlerin yapılmasını sağlar.

Bunu daha iyi anlayabilmek için, sırasıyla Callback, Promise ve Async/Await yapılarını inceleyelim.

Callback, Promise ve Async/Await: Temel Tanımlar ve Farklar



Callback, JavaScript'teki ilk asenkron çözüm şeklidir. Bir fonksiyonun parametresi olarak başka bir fonksiyon gönderilir ve işlem tamamlandığında bu callback fonksiyonu çalıştırılır. Ancak, uzun süreli işlemler söz konusu olduğunda, callback'ler karmaşıklaşır ve genellikle "callback hell" olarak adlandırılan bir duruma yol açar.


function getUserData(callback) {
  setTimeout(() => {
    callback("User Data");
  }, 2000);
}

getUserData(function(data) {
  console.log(data);
});


Promise, callback'lerin yerine geçerek daha temiz ve anlaşılır bir yapı sunar. Bir Promise, başarılı bir işlemde "resolve" edilirken, başarısızlık durumunda "reject" edilir. Promise zincirleme (chaining) yapılarıyla daha okunabilir ve yönetilebilir hale gelir.


function getUserData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("User Data");
    }, 2000);
  });
}

getUserData()
  .then(data => console.log(data))
  .catch(error => console.error(error));


Async/Await, Promise yapısını daha da basitleştiren bir başka yapı sunar. Asenkron işlemleri senkron gibi yazmanıza olanak tanır. Kodunuzu daha temiz ve anlaşılır kılar.


async function getUserData() {
  const data = await new Promise(resolve => {
    setTimeout(() => {
      resolve("User Data");
    }, 2000);
  });
  console.log(data);
}

getUserData();


En Yaygın Hatalar ve Yanlış Kullanımlar



Asenkron programlamada en sık karşılaşılan hatalardan biri, callback'lerin yanlış kullanılmasından kaynaklanır. Özellikle, callback fonksiyonlarının birden fazla seviyeye inmesi ("callback hell"), kodun okunabilirliğini ve bakımını zorlaştırır.

Promise'lerde ise, bir işlem tamamlanmadan önce başka bir işlemin başlatılması da sık yapılan bir hata olabilir. Ayrıca, `catch` bloklarını unutmamak, hataları düzgün bir şekilde yönetmek adına oldukça önemlidir.

Async/Await ile en yaygın hata, `await` anahtar kelimesinin doğru kullanılmamasıdır. Aslında, `await` sadece bir Promise ile çalışmalıdır, aksi takdirde beklenmedik sonuçlar alınabilir.

Performansı Artıran İpuçları: Hangi Durumda Hangi Yapıyı Kullanmalıyız?



- Eğer işlemler birbirini takip ediyorsa ve sırasıyla yapılması gerekiyorsa, Promise kullanmak en mantıklıdır. Kodunuz daha düzenli ve anlaşılır olur.
- Asenkron işlemlerin birbirinden bağımsız olduğu durumlarda, Promise.all gibi yöntemler ile birden fazla işlemi paralel çalıştırabilirsiniz.
- Async/Await, kodunuzu senkron gibi yazmanıza imkan verdiği için, okunabilirliği artırır ve hata yönetimini kolaylaştırır.

Örneğin, birden fazla veriyi paralel çekmeniz gereken bir durumu ele alalım:


async function fetchData() {
  const [userData, postData] = await Promise.all([
    fetch('https://api.example.com/user'),
    fetch('https://api.example.com/posts')
  ]);
  console.log(await userData.json());
  console.log(await postData.json());
}

fetchData();


Gerçek Hayattan Örnekler ve Kod Parçacıkları



İşte, asenkron programlamanın nasıl kullanılacağını daha iyi anlamanızı sağlayacak birkaç örnek.

Örneğin, bir e-ticaret uygulamasında, kullanıcı verilerini ve ürün bilgilerini çekmeniz gerekiyor. Bu tür işlemlerde, asenkron yapıların kullanımı performansı büyük ölçüde artıracaktır. Kod parçacıkları, hem kodunuzu daha sade tutacak hem de işlem sürelerini kısaltacaktır.

Performans Testleri: Callback, Promise ve Async/Await Arasındaki Farklar



Farklı asenkron yapıların performansını karşılaştırmak da önemlidir. İşte basit bir performans testi:


// Callback performans testi
function callbackTest() {
  let start = Date.now();
  for (let i = 0; i < 1000; i++) {
    setTimeout(() => {}, 0);
  }
  console.log('Callback: ', Date.now() - start);
}

// Promise performans testi
function promiseTest() {
  let start = Date.now();
  let promises = [];
  for (let i = 0; i < 1000; i++) {
    promises.push(Promise.resolve());
  }
  Promise.all(promises).then(() => {
    console.log('Promise: ', Date.now() - start);
  });
}

// Async/Await performans testi
async function asyncAwaitTest() {
  let start = Date.now();
  for (let i = 0; i < 1000; i++) {
    await Promise.resolve();
  }
  console.log('Async/Await: ', Date.now() - start);
}

callbackTest();
promiseTest();
asyncAwaitTest();


Sonuç



Asenkron programlama, JavaScript'in en güçlü özelliklerinden biridir. Callback, Promise ve Async/Await yapıları her biri farklı kullanım senaryolarına hitap eder ve doğru kullanım, uygulamanızın verimliliğini ve performansını önemli ölçüde artırabilir. Bu yazıda ele aldığımız temel farklar ve kullanım örnekleri sayesinde, hangi yapının hangi durumda kullanılacağını daha iyi kavrayabilirsiniz.

Unutmayın: Performans testleri yaparak, uygulamanız için en uygun çözümü bulmak her zaman en iyi yaklaşımdır. Asenkron kodlama, doğru yapıldığında, kullanıcı deneyimini iyileştirecek ve uygulamanızın hızını artıracaktır.

İlgili Yazılar

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

ASP.NET Core ile Mobil Uygulama Geliştirme: Cross-Platform Web ve Mobil Uygulama Birleştirme

Günümüzde mobil uygulamalar hayatımızın ayrılmaz bir parçası haline geldi. Akıllı telefonlarımızda geçirdiğimiz zamanın büyük bir kısmını mobil uygulamalar sayesinde geçiriyoruz. Peki, bir mobil uygulama geliştirirken karşılaştığımız zorlukları nasıl...

ASP.NET Core 500 Internal Server Error: Sebepleri ve Çözümleri

Bir web geliştiricisi olarak, karşılaştığınız en zorlayıcı hatalardan biri şüphesiz "500 Internal Server Error"dır. Bu hata, web uygulamanızda her şeyin yolunda gittiğini düşündüğünüz bir anda karşınıza çıkabilir ve tüm projeyi durdurabilir. Ancak merak...

OAuth2 Authentication Error: Nedenleri ve Çözümleri

OAuth2 Authentication Error: Gerçekten Neyin Peşindeyiz?Her geliştirici, kimlik doğrulama hatalarıyla bir noktada karşılaşmıştır. Ama bazen işler kontrolden çıkabiliyor. Eğer bir gün OAuth2 ile çalışırken bir kimlik doğrulama hatası aldığınızda, yalnız...