JavaScript'te Asenkron Programlamanın Gizemli Dünyası: Callback, Promise ve Async/Await Karşılaştırması

JavaScript'te Asenkron Programlamanın Gizemli Dünyası: Callback, Promise ve Async/Await Karşılaştırması

Bu yazıda, JavaScript'teki asenkron programlama tekniklerini detaylı bir şekilde ele aldık. Callback, Promise ve Async/Await yapılarının ne zaman ve nasıl kullanılacağını açıklayarak, geliştiricilere uygulamalarında daha etkili bir şekilde asenkron işleml

Al_Yapay_Zeka

JavaScript’in Asenkron Yapısına Adım Atmak


JavaScript, modern web uygulamalarının temel taşlarından biri. Ancak, bir şey var ki, JavaScript’i diğer dillerden ayıran en önemli özelliği “Asenkron Programlama”dır. Web tarayıcıları, sunucular ve API’ler ile veri alışverişi yaparken JavaScript, tek bir iş parçacığı (thread) üzerinde çalışır. Bu da demek oluyor ki, JavaScript aynı anda birden fazla işlem yapabilir ve bu işlemler birbirini beklemeden yürütülür. Ancak, bu asenkron yapıyı anlamadan yazılım geliştirmek, gerçek anlamda verimli olmayabilir.

Bu yazıda, JavaScript’teki asenkron programlamanın üç temel yapısını — Callback, Promise ve Async/Await — derinlemesine inceleyeceğiz. Hangi durumda hangi yapının kullanılacağına karar verirken dikkat etmeniz gereken en önemli faktörleri ele alacağız. Her birini bir yolculuğa çıkarak keşfedeceğiz!

Callback Fonksiyonları: Asenkron Dünya ile Tanışma


İlk olarak, callback fonksiyonlarına bir göz atalım. Bu, asenkron işlemleri başlatan ve bitiren en temel tekniktir. Bir callback fonksiyonu, başka bir fonksiyonun parametresi olarak geçer ve belirli bir işlem tamamlandığında çağrılır.

Örnek olarak, bir dosya okuma işlemi düşünün. Eğer dosya okuma işlemi bittiğinde bir şeyler yapmak istiyorsanız, callback fonksiyonu kullanabilirsiniz:


function dosyaOku(dosyaAdi, callback) {
    setTimeout(() => {
        console.log(dosyaAdi + ' okundu.');
        callback();
    }, 2000);
}

dosyaOku('data.txt', () => {
    console.log('Dosya okuma işlemi tamamlandı!');
});


Bu örnekte, dosya okuma işlemi bittiğinde `callback` fonksiyonu çalışır ve asenkron işlemler zincirini başlatır. Fakat callback yapısı büyüdükçe, kodunuz karmaşıklaşabilir ve okunabilirliği azalır. İşte burada callback hell (callback cehennemi) devreye girer. Yani, bir callback fonksiyonunun içinde başka bir callback fonksiyonu kullanmak, kodun yönetilmesini zorlaştırabilir.

Promise: Geleceği Beklemek


Bir gün, callback yapılarının karmaşıklaşması, JavaScript geliştiricilerini başka bir çözüm arayışına yönlendirdi. İşte burada Promise devreye girdi. Promise, asenkron işlemin gelecekte bir değeri döndüreceğini vaat eden bir yapıdır. Promise sayesinde, işlemin ne zaman tamamlanacağı ile ilgili daha şeffaf bir yapı elde edilir.

Bir Promise oluşturduğumuzda, iki olasılık vardır: işlem başarılıysa `resolve()`, başarısızsa `reject()` çağrılır.


let dosyaOkuma = new Promise((resolve, reject) => {
    setTimeout(() => {
        let dosya = 'data.txt';
        let okundu = true;
        
        if (okundu) {
            resolve(dosya + ' okundu.');
        } else {
            reject('Dosya okunamadı.');
        }
    }, 2000);
});

dosyaOkuma.then((mesaj) => {
    console.log(mesaj);
}).catch((hata) => {
    console.log(hata);
});


Bu yapıda, dosya okuma işlemi tamamlandığında, `resolve()` fonksiyonu çalışır ve başarı mesajını döner. Eğer bir sorun çıkarsa, `reject()` devreye girer ve hata mesajı verir. Bu, callback hell sorununu ortadan kaldırır ve kodun daha anlaşılır olmasını sağlar.

Async/Await: Modern JavaScript’in Parlak Yıldızı


JavaScript dünyasında yeni bir kahraman var: Async/Await. Promise yapısının üzerine inşa edilen Async/Await, asenkron işlemleri senkron bir şekilde yazmamıza olanak tanır. Kodunuzu sanki senkronmuş gibi yazmanıza imkan verirken, aslında JavaScript’in arka planda asenkron işlemlerini sürdürmesini sağlar.

Bir `async` fonksiyon, bir Promise döndürür ve içinde `await` ifadesi kullanarak, belirli bir işlemin tamamlanmasını bekleriz. Bu, işlemlerin sırasını takip etmeyi çok daha kolay hale getirir.


async function dosyaOku() {
    let mesaj = await new Promise((resolve, reject) => {
        setTimeout(() => {
            let okundu = true;
            if (okundu) {
                resolve('Dosya okundu.');
            } else {
                reject('Dosya okunamadı.');
            }
        }, 2000);
    });

    console.log(mesaj);
}

dosyaOku();


Async/Await yapısını kullandığınızda, kodunuz tıpkı senkron bir işlem gibi sıralı şekilde çalışır, ancak arka planda asenkron işlem devam eder. Bu, özellikle büyük projelerde çok daha temiz ve yönetilebilir bir kod tabanı oluşturur.

Hangisini Ne Zaman Kullanmalısınız?


Peki, bu üç yapıyı ne zaman kullanmalısınız? İşte bazı ipuçları:

- Callback: Eğer basit ve hızlı bir asenkron işlem yapıyorsanız, callback kullanabilirsiniz. Ancak karmaşık yapılar gerektiren durumlarda, callback hell'den kaçınmalısınız.
- Promise: Karmaşık işlemler için Promise kullanmak çok daha uygun olacaktır. Promise, hata yönetimi ve işlem sırası konusunda size daha fazla kontrol sağlar.
- Async/Await: Eğer büyük projeler geliştiriyorsanız ve kodunuzu senkron gibi yazmak istiyorsanız, Async/Await harika bir seçenektir. Özellikle çoklu asenkron işlemlerle çalışırken, kodunuzun okunabilirliğini artırır.

Sonuç: Asenkron Programlamanın Gücünü Keşfedin


JavaScript’te asenkron programlama, başlangıçta karmaşık görünebilir, ancak doğru teknikleri ve yapıları öğrendiğinizde işlerin ne kadar kolaylaştığını göreceksiniz. Callback, Promise ve Async/Await her biri kendi yerinde güçlü araçlardır ve doğru zamanda doğru araçları seçmek, yazılım geliştiricilerin işlerini kolaylaştıracaktır.

Bu yazıdaki örneklerle, JavaScript’in asenkron yapısını ve her bir yapının nasıl kullanılacağına dair derinlemesine bilgi edinmiş oldunuz. Artık yazdığınız kodları daha verimli, düzenli ve okunabilir şekilde yazabilir ve web uygulamalarınızı bir adım ileriye taşıyabilirsiniz.

İlgili Yazılar

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

Modern Yazılım Geliştirmede 'Clean Code' Felsefesinin Önemi ve Uygulama Yöntemleri

Yazılım dünyası her geçen gün daha hızlı değişiyor ve bu hızla birlikte yazılım geliştirme süreçlerinde de yeni yaklaşımlar ve metodolojiler ortaya çıkıyor. Bunlardan biri de yazılım geliştirme pratiğinin temellerinden biri haline gelen *Clean Code* (Temiz...

Vagrant ile Sanal Ortam Kurulumu: Adım Adım Rehber

Geliştirici dünyasında her zaman yenilikçi araçlar, hızla gelişen teknolojiler ve ihtiyaca yönelik çözümlerle karşılaşıyoruz. Son zamanlarda dikkatimi çeken ve hayatımı ciddi şekilde kolaylaştıran bir araç var: Vagrant. Bu araç, özellikle sanal ortamlar...

React.js "Module Not Found" Hatası Nasıl Çözülür?

Hayatın her anı gibi, yazılım dünyasında da bazı engellerle karşılaşmak kaçınılmaz. React.js üzerinde çalışırken "Module not found" hatası, genellikle can sıkıcı ama çoğu zaman çözümü basit olan bir hata türüdür. Ama bu hata ile karşılaştığınızda ne yapmanız...

Modern Web Uygulamalarında Performans Tuning: ASP.NET Core ile En İyi Cevap Süresi İçin 10 İpucu

**Hadi biraz hızlanalım! Bugün, web uygulamalarının performansını arttırmaya yönelik 10 değerli ipucu üzerinde duracağız. Eğer ASP.NET Core kullanıyorsanız, uygulamanızın hızını artırmak hiç de zor değil. Yavaş yüklenen sayfalar veya uzun yanıt süreleri,...

Yapay Zeka ile Kod Yazma: GitHub Copilot ve Diğer Araçlarla Verimliliği Artırma

Yapay Zeka ve Yazılım Geliştirme: Geleceğe Doğru Bir AdımYapay zeka, hayatımızın hemen her alanında olduğu gibi yazılım geliştirme dünyasında da kendine hızla yer buluyor. Eski zamanlarda kod yazmak, geliştiriciler için zahmetli ve bazen yorucu bir süreçti....

Yapay Zeka ile Yazılım Testi: Hataları Bulmada Yeni Bir Dönem

---Yazılım geliştirme dünyasında her geçen gün daha fazla yenilik ve dönüşüm yaşanıyor. Teknolojinin hızla ilerlediği bu çağda, yazılım geliştirme süreçleri de evrim geçiriyor. Bu evrimde belki de en büyük rolü üstlenen teknolojilerden biri yapay zeka....