1. Callbacks: Eski Ama Güçlü Bir Yöntem
Callbacks, JavaScript’in ilk asenkron işlem tekniklerinden biridir. Bu, bir fonksiyonun başka bir fonksiyona parametre olarak geçmesi ve işlem tamamlandığında çağrılmasıdır. Genellikle, bir işlemi tamamladıktan sonra başka bir işlemi başlatmak için kullanılır.
Örneğin, bir web sitesinde veri çekerken, verilerin çekilmesi uzun sürebilir. Bu durumda, bir callback fonksiyonu, veriler çekildikten sonra bir işlem yapmanızı sağlar:
function veriCek(callback) {
setTimeout(() => {
console.log("Veri çekildi!");
callback();
}, 2000);
}
veriCek(() => {
console.log("Veri kullanıldı.");
});
Burada, veri çekme işlemi tamamlandıktan sonra, callback fonksiyonu çalıştırılır. Ancak, callback hell olarak bilinen bir sorun burada devreye girer. Eğer çok sayıda asenkron işlem yapmanız gerekiyorsa, kodunuz iç içe geçmiş callback fonksiyonlarıyla karmaşık hale gelir. Bu, kodunuzu okunması ve bakımının zor hale gelmesine neden olur.
2. Promises: Callbacks’ın Daha Modern Bir Alternatifi
Promises (sözler), callback'lere göre daha modern bir yaklaşımdır ve JavaScript'teki asenkron işlemleri daha düzenli hale getirir. Promise, bir işlemin tamamlanıp tamamlanmadığını gösteren bir nesnedir. Bu nesne, işlemin başarılı olup olmadığını belirtir ve `.then()` ile başarılı sonuç, `.catch()` ile hatalar işlenir.
Örneğin:
function veriCek() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Veri çekildi!");
resolve();
}, 2000);
});
}
veriCek().then(() => {
console.log("Veri kullanıldı.");
}).catch((error) => {
console.log("Hata oluştu:", error);
});
Promises, callback hell sorununu çözmeye yardımcı olur çünkü işlemler birbirinden bağımsız olarak yönetilir. Ancak, yine de bazı durumlarda birbirini takip eden işlemleri yönetmek zor olabilir. Burada devreye async/await girmektedir.
3. Async/Await: En Okunabilir Asenkron Programlama
Async/Await, JavaScript’te asenkron kod yazma biçimini en okunabilir hale getiren yapıdır. Promise'leri çok daha anlaşılır bir şekilde yazmamızı sağlar. `async` fonksiyonları, Promise döner ve `await` ifadesi, Promise tamamlanana kadar kodun duraklamasını sağlar.
İşte bir örnek:
async function veriCek() {
console.log("Veri çekiliyor...");
await new Promise(resolve => setTimeout(resolve, 2000));
console.log("Veri çekildi!");
}
async function veriKullan() {
await veriCek();
console.log("Veri kullanıldı.");
}
veriKullan();
Bu kodda, `veriCek()` fonksiyonu bir Promise döner ve `await` ile bekleriz. Bu yapı, asenkron kodu çok daha sade ve anlaşılır kılar. Üstelik, callback hell ve promise zincirlerinden kaçınmamıza yardımcı olur.
4. Ne Zaman Hangi Yöntemi Kullanmalısınız?
Her bir asenkron işlem yöntemi belirli senaryolarda en iyi sonucu verir:
- Callbacks: Küçük ve basit işlemler için uygundur. Ancak, büyük projelerde callback hell'e dikkat edilmelidir.
- Promises: Birden fazla asenkron işlem yapmanız gerekiyorsa ve işlem sırasını yönetmek istiyorsanız promises idealdir.
- Async/Await: Okunabilirlik ve bakımı kolay bir kod istiyorsanız, `async/await` yapısını kullanmalısınız. Özellikle büyük ve karmaşık projelerde, kodunuzu sadeleştirir.
Sonuç olarak, JavaScript’te asenkron programlama öğrenmek başlangıçta zorlayıcı olabilir, ancak doğru yapılarla işler oldukça kolaylaşır. İhtiyacınıza göre en uygun asenkron yapıyı seçerek kodunuzu daha verimli hale getirebilirsiniz.