Herkese selamlar,
Başlıktaki iki kavramı açıklamadan önce senkron ve asenkron programlama kavramlarını anlamak promise ve async-await yapılarını anlamamızı kolaylaştıracaktır.
Senkron programlama çoğu yazılım dilinde varsayılan davranıştır.Kodlar satır satır okunur ve bir işlem bitmeden başka biri başlamaz.
Asenkron programlama ise zaman alan işlemlerin (API istekleri, dosya okuma-yazma, veritabanı sorguları, zamanlayıcılar) arka planda sürdürülmesini ve programın geri kalanının bu işlemler nedeniyle bloklanmadan çalışmasını sağlar. Bu şekilde, özellikle kullanıcı arayüzlerinin donmadan çalışması ve yüksek performanslı uygulamalar geliştirilmesi açısından büyük önem taşır.
Javascript’te asenkron işlemleri kontrollü biçimde ele alıp doğru şekilde hata yönetimi yapabilmek için promise, async-await yapıları kullanılır.
Promise
Asenkron işlemleri kontrollü şekilde yönetmek için promise nesnesi kullanılır.
Örneğin bir endpointe get metodu ile istek atıp kullanıcının gönderisini getirmek istiyoruz.
function getPost() {
return new Promise((resolve, reject) => {
https
.get("https://jsonplaceholder.typicode.com/posts/1", (res) => {
let data = "";
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
if (res.statusCode >= 200 && res.statusCode < 300) {
try {
resolve(JSON.parse(data));
} catch (e) {
reject("JSON parse hatası: " + e.message);
}
} else {
reject(`Sunucu hatası: ${res.statusCode}`);
}
});
})
.on("error", (err) => {
reject("İstek başarısız: " + err.message);
});
});
}
getPost()
.then((post) => console.log("Post verisi:", post))
.catch((err) => console.error("Hata:", err));
-
Promise constructor bir executor fonksiyonu bekler.
(resolve,reject)=>{} -
resolveişlem başarıyla çağrılacak fonksiyon verejectişlem başarısızsa çağrılacak fonksiyondur. -
then()işlem bittiğinde verdiğimiz callback fonksiyonunu çalıştırır.
resolve(parametre)başarılı işlemde resolve içine verdiğimiz parametre
then(function(result){})metodundaki callback fonksiyonuna parametre olarak verilir. -
catch()işlem sırasında veya bittiğinde sonuçta hata varsa callback fonksiyonunu çalıştırır.reject(parametre)metodu içindeki parametrecatch(function(error){})metodundaki callback fonksiyonuna parametre olarak verilir. -
finallypromise başarılı, başarısız, hatalı gibi her durumdan bağımsız çalıştırmak istediğimiz zaman kullanılır.finally(() => console.log("İstek tamamlandı"));gibi kullanıcıyı bilgilendirmek için kullanılabilir.
Promise durumları (state) şunlardır:
-
pendingHenüz sonuçlanmadı, beklemede. -
fulfilledİşlem başarıyla tamamlandı,resolve()çağrıldı. -
rejectedİşlem başarısız oldu,reject()çağrıldı.
Async – Await
Bu kullanım ES8 (ECMAScript 2017) standartıyla ile javascript’e eklenmiştir.
Promise ile verdiğimiz örneği async-await ile kullanmak istersek:
async function fetchPost() {
try {
const post = await getPost();
console.log("Post verisi:", post);
} catch (err) {
console.error("Hata:", err);
}
}
fetchPost();
-
asyncanahtar kelimesiyle tanımlanan fonskyionPromisenesnesi döner. -
awaitsadece async ile işaretlenen fonksiyon içinde kullanılır. Promise’in çözülmesini (resolve) bekler. Kod bloğu kendi scope’u içerisinde bloklanır. -
try-catchyapısıyla hata yönetimirejectdurumu yönetilir.
Zincirleme then kullanımı ve async-await ile karşılaştırması
function getData() {
return new Promise(resolve => {
setTimeout(() => resolve({ users: [{ id: 42, name: "Ayşe" }] }), 500);
});
}
function getUserId(data) {
return new Promise(resolve => {
setTimeout(() => resolve(data.users[0].id), 500);
});
}
function getUserPost(userId) {
return new Promise(resolve => {
setTimeout(() => resolve([{ id: 1, userId, title: "Post Başlığı" }]), 500);
});
}
getData()
.then(getUserId)
.then(getUserPost)
.then(posts => console.log("Postlar:", posts))
.catch(err => console.error("Hata:", err))
.finally(() => console.log("Tamamlandı"));
async function fetchUserPosts() {
try {
const data = await getData();
const userId = await getUserId(data);
const posts = await getUserPost(userId);
console.log("Postlar:", posts);
} catch (err) {
console.error("Hata:", err);
} finally {
console.log("Tamamlandı");
}
}
fetchUserPosts();