JavaScript: Başlangıçtan İleri Seviyeye
Bölüm 17 / 312 dk okuma

Promises

Asenkron işlemleri yönetmenin modern yolu, callback hell'den çıkış.

Promise, gelecekte tamamlanacak bir işin temsilcisidir. 3 hâli var:

  • Pending (beklemede)
  • Fulfilled (başarılı, bir değer var)
  • Rejected (başarısız, bir hata var)

Bir promise bir kez "settle" olur (fulfill veya reject), sonra durumu değişmez.

Tüketmek (then/catch/finally)

fetch("/api/users")
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((err) => console.error("Hata:", err))
  .finally(() => console.log("Bitti"));

then ile zincirleme: her then'in dönüş değeri sonraki then'in argümanı olur. Bir promise dönerse otomatik "unwrap" edilir.

Üretmek (new Promise)

function bekle(ms) {
  return new Promise((resolve, reject) => {
    if (ms < 0) reject(new Error("Negatif ms"));
    setTimeout(() => resolve(`${ms}ms beklendi`), ms);
  });
}
 
bekle(1000).then((mesaj) => console.log(mesaj));

resolve(value) çağrılırsa fulfilled, reject(err) çağrılırsa rejected olur. Yalnızca ilki etkili olur.

Callback hell vs promise zinciri

Eski callback yaklaşımı:

getUser(id, (user) => {
  getOrders(user.id, (orders) => {
    getProduct(orders[0].productId, (product) => {
      console.log(product);
    }, errHandler);
  }, errHandler);
}, errHandler);

Promise ile:

getUser(id)
  .then((user) => getOrders(user.id))
  .then((orders) => getProduct(orders[0].productId))
  .then((product) => console.log(product))
  .catch(errHandler);

Statik metotlar

Promise.all — hepsi bitsin

const [user, posts, comments] = await Promise.all([
  fetch("/api/user").then((r) => r.json()),
  fetch("/api/posts").then((r) => r.json()),
  fetch("/api/comments").then((r) => r.json()),
]);

Birisi reject olursa tümü reject olur.

Promise.allSettled — biri hata verse de devam et

const sonuclar = await Promise.allSettled([p1, p2, p3]);
sonuclar.forEach((s) => {
  if (s.status === "fulfilled") console.log(s.value);
  else console.error(s.reason);
});

Promise.race — ilk biten kazanır

const sonuc = await Promise.race([
  fetch("/api/data"),
  bekle(5000).then(() => { throw new Error("timeout"); }),
]);

Timeout pattern'i için klasik kullanım.

Promise.any — ilk başaranı al

// İlk fulfilled olanı döner. Hepsi reject olursa AggregateError atar.
const ilk = await Promise.any([cdn1, cdn2, cdn3]);

Microtask sırası

Promise callback'leri microtask queue'ya girer. setTimeout'tan önce çalışırlar:

console.log(1);
setTimeout(() => console.log(2));
Promise.resolve().then(() => console.log(3));
console.log(4);
// 1, 4, 3, 2
Önemli

Promise zincirinde catch koymayı unutma! Yakalanmayan reject "Unhandled Promise Rejection" uyarısı üretir ve modern Node.js'te process'i sonlandırır.

Bu bölümü bitirdin mi?

İlerlemen tarayıcıda saklanır, eğitim listesinde görünür.

Paylaş