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)=>{}
-
resolve
işlem başarıyla çağrılacak fonksiyon vereject
iş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. -
finally
promise 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:
-
pending
Henü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();
-
async
anahtar kelimesiyle tanımlanan fonskyionPromise
nesnesi döner. -
await
sadece 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-catch
yapısıyla hata yönetimireject
durumu 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();