Giriş
JavaScript, varsayılan olarak senkron bir dildir. Ancak, web uygulamalarında dosya yükleme, API çağrıları veya veritabanı işlemleri gibi uzun sürebilecek görevler sıklıkla karşımıza çıkar. Bu tür görevler, ana iş parçacığını (main thread) bloke ederek uygulamanın donmasına neden olabilir. İşte bu noktada asenkron programlama devreye girer.
Neden Promise'lar?
Geçmişte asenkron işlemleri yönetmek için geri arama fonksiyonları (callbacks) yoğun olarak kullanılırdı. Ancak, iç içe geçmiş çok sayıda geri arama fonksiyonu "callback hell" (geri arama cehennemi) olarak bilinen karmaşık ve okunması zor bir kod yapısına yol açabiliyordu. Promise'lar, bu sorunu çözmek ve asenkron kodun daha düzenli, okunabilir ve yönetilebilir olmasını sağlamak amacıyla ortaya çıkmıştır.
Promise Nedir?
Bir Promise (Söz), asenkron bir işlemin nihai tamamlanmasını (veya başarısızlığını) temsil eden bir JavaScript nesnesidir. Bir Promise, üç ana durumdan birinde olabilir:
Promise Oluşturma ve Kullanımı
Yeni bir Promise, `new Promise()` yapıcısı ile oluşturulur. Bu yapılandırıcının içine bir yürütme fonksiyonu (executor function) geçeriz. Bu fonksiyon, iki argüman alır: `resolve` ve `reject`.
Oluşturduğumuz Promise'ı kullanmak için `.then()`, `.catch()` ve isteğe bağlı olarak `.finally()` metotlarını kullanırız:
Promise Zincirleme
Promise'lar, .then() metodu aracılığıyla birbirine zincirlenebilir. Her .then() çağrısı yeni bir Promise döndürür ve bu sayede asenkron işlemler sıralı bir şekilde yürütülebilir.
Ek Promise Metotları
JavaScript, Promise'larla birlikte kullanılabilecek bazı yardımcı metotlar sunar:
Async/Await ile Daha Kolay Yönetim
ES2017 ile birlikte tanıtılan async/await söz dizimi, Promise'lar üzerinde çalışan ve asenkron kodu senkron kod gibi yazmamıza olanak tanıyan bir kolaylaştırıcıdır. Temelde Promise'ları kullanır ancak söz dizimi daha temiz ve okunabilirdir.
Sonuç
Promise'lar, JavaScript'te asenkron işlemleri yönetmek için güçlü ve temel bir yapıdır. Callback hell sorununu çözerek daha okunabilir ve sürdürülebilir kod yazmamızı sağlarlar. Modern JavaScript geliştirmede async/await ile birlikte Promise'lar, asenkron akışı yönetmenin vazgeçilmez bir parçasıdır. Bu yapıları anlamak, daha sağlam ve performanslı web uygulamaları geliştirmek için kritik öneme sahiptir.
JavaScript, varsayılan olarak senkron bir dildir. Ancak, web uygulamalarında dosya yükleme, API çağrıları veya veritabanı işlemleri gibi uzun sürebilecek görevler sıklıkla karşımıza çıkar. Bu tür görevler, ana iş parçacığını (main thread) bloke ederek uygulamanın donmasına neden olabilir. İşte bu noktada asenkron programlama devreye girer.
Neden Promise'lar?
Geçmişte asenkron işlemleri yönetmek için geri arama fonksiyonları (callbacks) yoğun olarak kullanılırdı. Ancak, iç içe geçmiş çok sayıda geri arama fonksiyonu "callback hell" (geri arama cehennemi) olarak bilinen karmaşık ve okunması zor bir kod yapısına yol açabiliyordu. Promise'lar, bu sorunu çözmek ve asenkron kodun daha düzenli, okunabilir ve yönetilebilir olmasını sağlamak amacıyla ortaya çıkmıştır.
Promise Nedir?
Bir Promise (Söz), asenkron bir işlemin nihai tamamlanmasını (veya başarısızlığını) temsil eden bir JavaScript nesnesidir. Bir Promise, üç ana durumdan birinde olabilir:
- Pending (Beklemede): İşlem henüz tamamlanmamış veya reddedilmemiştir.
- Fulfilled/Resolved (Tamamlandı/Başarılı): İşlem başarıyla tamamlandı.
- Rejected (Reddedildi/Başarısız): İşlem bir hata nedeniyle başarısız oldu.
Promise Oluşturma ve Kullanımı
Yeni bir Promise, `new Promise()` yapıcısı ile oluşturulur. Bu yapılandırıcının içine bir yürütme fonksiyonu (executor function) geçeriz. Bu fonksiyon, iki argüman alır: `resolve` ve `reject`.
Kod:
const myPromise = new Promise((resolve, reject) => {
// Asenkron bir işlem yapıyoruz
const success = true; // Bu değer bir API çağrısı veya veritabanı işleminden gelebilir
if (success) {
resolve("Veriler başarıyla alındı!"); // İşlem başarılı
} else {
reject("Veri alımında bir hata oluştu."); // İşlem başarısız
}
});
Oluşturduğumuz Promise'ı kullanmak için `.then()`, `.catch()` ve isteğe bağlı olarak `.finally()` metotlarını kullanırız:
- .then(): Promise başarıyla tamamlandığında çalışacak kodu tanımlar. Zincirleme Promise'lar için de kullanılır.
- .catch(): Promise reddedildiğinde veya zincirdeki herhangi bir Promise'da hata oluştuğunda çalışacak kodu tanımlar.
- .finally(): Promise'ın başarılı veya başarısız olmasına bakılmaksızın her zaman çalışacak kodu tanımlar.
Kod:
myPromise
.then((message) => {
console.log(message); // "Veriler başarıyla alındı!"
})
.catch((error) => {
console.error(error); // "Veri alımında bir hata oluştu."
})
.finally(() => {
console.log("Promise işlemi tamamlandı.");
});
Promise Zincirleme
Promise'lar, .then() metodu aracılığıyla birbirine zincirlenebilir. Her .then() çağrısı yeni bir Promise döndürür ve bu sayede asenkron işlemler sıralı bir şekilde yürütülebilir.
Kod:
function fetchData(id) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(`Kullanıcı ${id} verileri.`);
}, 1000);
});
}
fetchData(1)
.then(data => {
console.log(data); // "Kullanıcı 1 verileri."
return fetchData(2); // Yeni bir Promise döndürüyoruz
})
.then(data => {
console.log(data); // "Kullanıcı 2 verileri."
})
.catch(error => {
console.error(error);
});
Ek Promise Metotları
JavaScript, Promise'larla birlikte kullanılabilecek bazı yardımcı metotlar sunar:
- Promise.all(iterable): Tüm Promise'lar başarılı olduğunda tamamlanan tek bir Promise döndürür. Herhangi biri başarısız olursa, ilk başarısız olanın hatasını döndürür.
- Promise.race(iterable): Iterable içindeki ilk tamamlanan (başarılı veya başarısız) Promise ile aynı şekilde tamamlanan tek bir Promise döndürür.
- Promise.resolve(value): Belirtilen değerle başarıyla çözülmüş bir Promise döndürür.
- Promise.reject(reason): Belirtilen nedenle reddedilmiş bir Promise döndürür.
Async/Await ile Daha Kolay Yönetim
ES2017 ile birlikte tanıtılan async/await söz dizimi, Promise'lar üzerinde çalışan ve asenkron kodu senkron kod gibi yazmamıza olanak tanıyan bir kolaylaştırıcıdır. Temelde Promise'ları kullanır ancak söz dizimi daha temiz ve okunabilirdir.
Kod:
async function getUserData() {
try {
const user = await fetchData(3); // fetchData Promise döndürüyor
console.log(user);
const details = await fetchData(user.id + "_detay"); // Zincirleme gibi
console.log(details);
} catch (error) {
console.error("Hata:", error);
}
}
getUserData();
Sonuç
Promise'lar, JavaScript'te asenkron işlemleri yönetmek için güçlü ve temel bir yapıdır. Callback hell sorununu çözerek daha okunabilir ve sürdürülebilir kod yazmamızı sağlarlar. Modern JavaScript geliştirmede async/await ile birlikte Promise'lar, asenkron akışı yönetmenin vazgeçilmez bir parçasıdır. Bu yapıları anlamak, daha sağlam ve performanslı web uygulamaları geliştirmek için kritik öneme sahiptir.