Yazılarımız

OfisData

JAVASCRIPT ASYNC AWAIT PROMISE YÖNETMEK

Sarı JS kare logosu yanında iki yatay akış senkron düz çizgi ve asenkron kavisli kesik çizgi Promise üç durum dairesi pending fulfilled rejected

JavaScript'in asenkron yapısı modern web'in temelidir. Bir butona tıklandığında sunucudan veri çekilir; sayfa donmaz, kullanıcı diğer işlere devam edebilir. Bu davranışın altında Promise vardır. async/await ise Promise'leri yazmayı senkron koda benzer şekilde okunaklı yapar.

Promise mantığı yıllarca callback hell'i çözdü. async/await syntax'ı ise Promise zincirlerini daha temiz okunabilir hale getirdi; davranışın ince ayrıntıları için web teknolojileri dokümantasyonu ayrıntılı bir başvuru kaynağı sağlar. Modern JavaScript hâlâ Promise'lere dayanıyor; async/await sadece bir görsel kabuk.

Promise temelleri oturmadan yazılan async/await, çalışan ama anlaşılmayan kod üretir — hata yönetimi atlanır, paralel çalıştırma fırsatları sıralı beklemeye döner ve tuzaklar üretimde patlar. Bu yüzden sıra önemli: önce Promise''in kendisi, sonra syntax şekeri, en sonda da tuzak haritası.

Promise nedir?

Henüz tamamlanmamış bir asenkron işlemin sonucunu temsil eden nesne. Üç durumdan biri:

  • Pending: İşlem devam ediyor
  • Fulfilled: İşlem başarıyla tamamlandı
  • Rejected: İşlem hata ile sonuçlandı

Temel Promise yapısı

const veri = new Promise((resolve, reject) => {
  setTimeout(() => {
    const sonuc = Math.random();
    if (sonuc > 0.5) {
      resolve(sonuc);
    } else {
      reject(new Error('Yetersiz değer'));
    }
  }, 1000);
});

veri
  .then(deger => console.log('Başarılı:', deger))
  .catch(hata => console.error('Hata:', hata));

async/await syntax

Aynı kodu daha okunabilir yazmak için:

async function veriCek() {
  try {
    const sonuc = await veri;
    console.log('Başarılı:', sonuc);
  } catch (hata) {
    console.error('Hata:', hata);
  }
}

veriCek();

İki kural:

  • async: Bir fonksiyonu Promise döndüren fonksiyona çevirir
  • await: Promise'in tamamlanmasını bekler; sadece async fonksiyon içinde kullanılır

fetch ile gerçek örnek

// Promise zinciri ile
fetch('/api/urunler')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

// async/await ile (daha okunabilir)
async function urunleriGetir() {
  try {
    const response = await fetch('/api/urunler');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

İkisi de aynı işi yapıyor; async/await daha senkron-benzeri okunuyor.

Hata yönetimi

try/catch ile

async function islem() {
  try {
    const sonuc = await riskliIslem();
    return sonuc;
  } catch (error) {
    if (error.code === 'NETWORK_ERROR') {
      console.log('İnternet bağlantısı yok');
    } else {
      console.error('Bilinmeyen hata:', error);
    }
    throw error; // gerekirse yukarı fırlat
  }
}

.catch() ile

islem()
  .then(sonuc => console.log(sonuc))
  .catch(error => console.error(error))
  .finally(() => console.log('Bitti'));

finally hata olsun olmasın her zaman çalışır; loading state kapatma gibi temizlik işleri için.

Paralel çalıştırma: Promise.all

Birden fazla bağımsız Promise'i paralel çalıştırmak için.

// Yanlış: sırayla bekler (yavaş)
async function yavasYol() {
  const kullanici = await fetch('/api/user');
  const siparisler = await fetch('/api/orders');
  const yorumlar = await fetch('/api/reviews');
  // Toplam 3 saniye (her biri 1sn)
}

// Doğru: paralel (hızlı)
async function hizliYol() {
  const [kullanici, siparisler, yorumlar] = await Promise.all([
    fetch('/api/user'),
    fetch('/api/orders'),
    fetch('/api/reviews')
  ]);
  // Toplam 1 saniye (en yavaşı kadar)
}

Promise.all biri başarısız olursa tümü başarısız sayılır. Bunu engellemek için Promise.allSettled kullanılır.

Promise.allSettled, Promise.race, Promise.any

MethodDavranış
Promise.allTümünü bekler; biri hata verirse hep hata
Promise.allSettledTümünü bekler; her birinin status ve value/reason'ı döner
Promise.raceİlk tamamlananı döner (başarı veya hata)
Promise.anyİlk BAŞARILIYI döner; tümü hata verirse hata
VS Code dark tema editörde async fonksiyon içinde await fetch ve try catch hata yakalama bloklarının syntax highlighted JavaScript kodu

Klasik Hatalar hatalar

1. await unutmak

// Yanlış
async function getir() {
  const data = fetch('/api'); // await unutuldu
  return data.json(); // hata: data Promise nesnesi
}

// Doğru
async function getir() {
  const data = await fetch('/api');
  return data.json();
}

2. forEach içinde await

// Yanlış: forEach await beklemez
[1, 2, 3].forEach(async (id) => {
  await islem(id);
});
console.log('bitti'); // önce yazılır

// Doğru: for...of veya Promise.all
for (const id of [1, 2, 3]) {
  await islem(id);
}
// veya paralel
await Promise.all([1, 2, 3].map(islem));

3. Try/catch içinde await olmadan

// Yanlış: hata yakalanmaz
async function islem() {
  try {
    return riskliPromise(); // await yok
  } catch (e) {
    // bu blok çalışmaz; Promise hatası dışarı çıkar
  }
}

// Doğru
async function islem() {
  try {
    return await riskliPromise();
  } catch (e) {
    console.error(e);
  }
}

4. Çoklu reject yakalama

// Yanlış: tek catch yetersiz
Promise.all([istek1, istek2, istek3])
  .catch(e => console.error(e));
// İlk reject yakalanır; diğer hatalar görünmez

// Doğru: allSettled
const sonuclar = await Promise.allSettled([istek1, istek2, istek3]);
sonuclar.forEach(sonuc => {
  if (sonuc.status === 'rejected') {
    console.error(sonuc.reason);
  }
});

Async iteration

Asenkron veriler üzerinde for...of benzeri döngü:

async function* sayilar() {
  yield 1;
  yield 2;
  yield 3;
}

for await (const num of sayilar()) {
  console.log(num);
}

Stream'ler için tipik kullanım; satır satır gelen veriyi sırayla işleme.

Timeout ve cancel

JavaScript Promise'leri yerleşik cancel etmez. Modern çözüm AbortController:

const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);

try {
  const response = await fetch('/api', {
    signal: controller.signal
  });
  clearTimeout(timeoutId);
  return await response.json();
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('İstek 5 saniyede bitmediği için iptal');
  }
}

Performance ipuçları

  • Bağımsız işleri paralel yap. Promise.all ile zaman tasarrufu
  • Promise'leri yeniden kullan. Aynı verinin tekrar çekilmesi yerine cache
  • Stream kullan. Büyük veri için tek seferde değil parça parça
  • AbortController ile iptal et. Gereksiz istek devam etmesin
  • Microtask spam'ından kaçın. Sonsuz Promise zinciri main thread'i tüketir
Paralel ve seri Promise çalıştırma zaman çizgisi karşılaştırması üstte üç ardışık await coral mavi amber bloğu altta Promise all ile aynı anda yan yana üç blok

Sonraki Adım Setleri

Async/await ve Promise modern JavaScript'in temel becerilerinden. Konuyu profesyonel düzeyde işlemek için kapsamlı JavaScript eğitimi programları asenkron programlama konularını derinlemesine işler.

Kritik Detaylar

JavaScript async/await syntax'ı Promise'lerin görsel kabuğu; altta hâlâ Promise mantığı var. try/catch ile hata yönetimi, Promise.all ile paralel çalıştırma, AbortController ile iptal modern asenkron kodun temel araçları. await unutmak, forEach içinde await kullanmak, Promise.all yerine sıralı await yazmak yaygın hatalar. Doğru kullanım hem performans hem okunabilirlik için kritik.

 Vimaj