JAVASCRIPT // VANILLA JSD::02 BAŞLANGIÇ+
10m READCOMPLETION: 92%ID::JS-101

JAVASCRIPT ASYNC/AWAIT VE PROMISE CHAIN

Asenkron programlama, event loop ve hata yönetimi

JavaScript, web'in tek evrensel programlama dilidir. Tarayıcıda, sunucuda (Node.js) ve mobilde (React Native) çalışır. Bu derste modern ES2022+ söz dizimiyle temelden başlıyoruz.

Değişkenler ve Tipler

// JAVASCRIPT //
// let — yeniden atanabilir
let sayac = 0;
sayac = 1; // OK
 
// const — referans değiştirilemez (nesne içeriği değişebilir)
const PI = 3.14159;
const kullanici = { ad: 'Ali', yas: 25 };
kullanici.yas = 26; // OK — nesne içeriği değişti, referans değil
 
// Primitif tipler
const metin   = 'Merhaba';       // string
const sayi    = 42;               // number
const ondalik = 3.14;             // number (float yok)
const dogruMu = true;             // boolean
const hic     = null;             // null
const tanim   = undefined;        // undefined
const buyukSayi = 9007199254740993n; // BigInt
const sembol  = Symbol('id');     // Symbol

Fonksiyonlar

// JAVASCRIPT //
// Function declaration — hoisted
function topla(a, b) {
  return a + b;
}
 
// Arrow function — kısa sözdizim, this bağlamayı miras alır
const carp = (a, b) => a * b;
 
// Default parametreler
const selamla = (ad, selam = 'Merhaba') => `${selam}, ${ad}!`;
console.log(selamla('Ayşe'));         // Merhaba, Ayşe!
console.log(selamla('Mehmet', 'Hey')); // Hey, Mehmet!
 
// Rest parametresi
const toplamHesapla = (...sayilar) => sayilar.reduce((acc, n) => acc + n, 0);
console.log(toplamHesapla(1, 2, 3, 4, 5)); // 15
 
// Destructuring parametreler
function kullaniciBilgisi({ ad, yas, sehir = 'İstanbul' }) {
  return `${ad} (${yas}) — ${sehir}`;
}
console.log(kullaniciBilgisi({ ad: 'Zeynep', yas: 28 }));
// Zeynep (28) — İstanbul

Diziler ve Nesneler

// JAVASCRIPT //
// Dizi metodları (immutable yaklaşım)
const sayilar = [3, 1, 4, 1, 5, 9, 2, 6];
 
const ciftler = sayilar.filter(n => n % 2 === 0);  // [4, 6, 2] değil → [4, 2, 6]
const kareler = sayilar.map(n => n ** 2);           // [9, 1, 16, 1, 25, 81, 4, 36]
const toplam  = sayilar.reduce((acc, n) => acc + n, 0); // 31
const ilkBes  = sayilar.find(n => n > 4);           // 5
 
// Spread operatörü — kopyalama ve birleştirme
const yeniSayilar = [...sayilar, 7, 8];
const ilkUc = sayilar.slice(0, 3); // [3, 1, 4]
 
// Nesne destructuring
const { ad, yas, ...kalanlar } = { ad: 'Ali', yas: 25, sehir: 'Ankara', job: 'dev' };
console.log(ad);       // Ali
console.log(kalanlar); // { sehir: 'Ankara', job: 'dev' }
 
// Nesne spread ile güncelleme
const kullanici = { id: 1, ad: 'Ali', rol: 'user' };
const guncel    = { ...kullanici, rol: 'admin', guncellendi: new Date() };
// Orijinal kullanici değişmez

Asenkron Programlama

// JAVASCRIPT //
// Promise zinciri
fetch('/api/kullanicilar')
  .then(res => {
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    return res.json();
  })
  .then(veri => console.log(veri))
  .catch(hata => console.error('Hata:', hata.message));
 
// async/await — çok daha okunabilir
async function kullanicilariGetir() {
  try {
    const res = await fetch('/api/kullanicilar');
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const veri = await res.json();
    return veri;
  } catch (hata) {
    console.error('Hata:', hata.message);
    throw hata; // Üst katmana ilet
  }
}
 
// Paralel istekler — daha hızlı
async function parallelVeriCek(kullaniciId, siparisId) {
  const [kullanici, siparis] = await Promise.all([
    fetch(`/api/kullanicilar/${kullaniciId}`).then(r => r.json()),
    fetch(`/api/siparisler/${siparisId}`).then(r => r.json()),
  ]);
  return { kullanici, siparis };
}

Optional Chaining ve Nullish Coalescing

// JAVASCRIPT //
const kullanici = {
  profil: {
    adres: {
      sehir: 'İzmir'
    }
  }
};
 
// Eski yöntem — verbose ve hataya açık
const sehir1 = kullanici && kullanici.profil && kullanici.profil.adres
  ? kullanici.profil.adres.sehir
  : 'Bilinmiyor';
 
// Modern yöntem — optional chaining
const sehir2 = kullanici?.profil?.adres?.sehir ?? 'Bilinmiyor';
 
// Nullish coalescing — sadece null/undefined için fallback (0 ve '' korunur)
const sayfaBoyutu = kullanici?.ayarlar?.sayfaBoyutu ?? 20;
const baslik = kullanici?.baslik || 'Anonim'; // YANLIŞ: 0 ve '' yanlış sayılır
const baslik2 = kullanici?.baslik ?? 'Anonim'; // DOĞRU

Modüller

// JAVASCRIPT //
// math.js — named exports
export const PI = 3.14159;
export function topla(a, b) { return a + b; }
export function carp(a, b) { return a * b; }
 
// default export
export default class Hesaplama {
  constructor(baslangic = 0) {
    this.deger = baslangic;
  }
  ekle(n) { this.deger += n; return this; }
  sonuc() { return this.deger; }
}
 
// main.js — import
import Hesaplama, { PI, topla } from './math.js';
 
const h = new Hesaplama(10).ekle(5).ekle(3);
console.log(h.sonuc()); // 18
console.log(`PI ≈ ${PI}`);

Pratik: Kullanıcı Yönetimi Sınıfı

// JAVASCRIPT //
class KullaniciDeposu {
  #kullanicilar = new Map(); // Private field
 
  ekle(kullanici) {
    if (!kullanici.id || !kullanici.email) {
      throw new Error('id ve email zorunludur');
    }
    this.#kullanicilar.set(kullanici.id, {
      ...kullanici,
      olusturuldu: new Date(),
    });
    return this;
  }
 
  bul(id) {
    return this.#kullanicilar.get(id) ?? null;
  }
 
  emailIleBul(email) {
    return [...this.#kullanicilar.values()]
      .find(k => k.email === email) ?? null;
  }
 
  sil(id) {
    return this.#kullanicilar.delete(id);
  }
 
  get sayi() {
    return this.#kullanicilar.size;
  }
 
  listeAl(filtre = () => true) {
    return [...this.#kullanicilar.values()].filter(filtre);
  }
}
 
// Kullanım
const depo = new KullaniciDeposu();
depo
  .ekle({ id: '1', ad: 'Ali', email: 'ali@test.com', rol: 'admin' })
  .ekle({ id: '2', ad: 'Ayşe', email: 'ayse@test.com', rol: 'user' });
 
console.log(depo.sayi);                        // 2
console.log(depo.bul('1').ad);                 // Ali
const adminler = depo.listeAl(k => k.rol === 'admin');

Sonuç

Modern JavaScript, const/let, arrow function, destructuring, async/await ve optional chaining ile çok daha güvenli ve okunabilir bir dil haline geldi. Bir sonraki derste TypeScript ile bu temeli tip güvenliğiyle pekiştireceğiz.