---
title: 'Askıya Alma ve Yükleniyor Durumları'
source: 'https://academia.sh/tr/kurslar/bilesen-tabanli-gelistirme/askiya-alma-ve-yukleniyor-durumlari'
course: 'Bileşen Tabanlı Arayüz Geliştirme'
language: tr
updated: '2026-08-17T18:09:13+00:00'
license: 'CC BY-SA 4.0'
---

# Askıya Alma ve Yükleniyor Durumları

Verisi hazır olmayan bileşenin oluşturmayı kesip en yakın bekleme sınırına sinyal vermesi; elle tutulan bayrakların ürettiği geçersiz bileşimler, sınır yerleşiminin açığa çıkardığı istek şelalesi, gösterge titremesinin ölçüsü ve geçişlerde eski içeriğin korunması.

Önceki ders bir alt ağacın **başarısız olduğu** durumu ağacın geri kalanından ayırdı.
Ayrılması gereken ikinci bir durum daha vardır: alt ağacın henüz **hazır olmadığı** durum.
Ölçüm tablosu, veriler sunucudan gelene kadar çizilemez; karşılaştırma panosu ikinci
istasyonun kayıtlarını bekler.

İki durum arasındaki benzerlik yapısaldır. Her ikisinde de bir bileşen kendi başına
çözemediği bir sorunla karşılaşır ve bunu yukarıya bildirir; yukarıdaki bir sınır bildirimi
yakalar ve alt ağacın yerine başka bir görünüm koyar. Bu derste ikinci mekanizmaya **askıya
alma (suspension)**, onu yakalayan bileşene **bekleme sınırı** denecektir.

## Elle Tutulan Bayrakların Sorunu

Yaygın çözüm her bileşende üç ayrı durum tutmaktır: veri, yükleniyor bayrağı ve hata.
Üç ayrı yuva sekiz bileşim üretir ve bunların yalnız üçü anlamlıdır — yükleniyor, hata,
veri. Kalan beş bileşim geçersizdir: hem yükleniyor hem hatalı, hem veri var hem
yükleniyor, üçü birden boş.

Geçersiz bileşimler kod içinde ortaya çıkmaz, kenar durumlarda çıkar: ikinci istek
başlatılırken hata bayrağı sıfırlanmazsa ekranda hem gösterge hem hata iletisi görünür.
Bunu önlemenin yolu üç bayrağı tek bir ayrık durumla değiştirmektir; ama o zaman da her
bileşen kendi ayrık durumunu, kendi göstergesini ve kendi hata görünümünü taşır. Sayfada
altı veri okuyan bileşen varsa altı ayrı gösterge döner.

Askıya alma bu iki sorunu birden çözer: bileşen "hazır değilim" demenin dışında hiçbir
durum tutmaz, gösterge kararı yukarıya toplanır.

## Askıya Alma

Bileşen, verisini okumaya çalışır. Veri hazırsa değeri alır ve oluşturmayı sürdürür. Hazır
değilse isteği başlatır ve oluşturmayı keser. Kesme yukarı çıkar, en yakın bekleme sınırında
durur, o sınır alt ağacın yerine bekleme görünümünü koyar. Veri geldiğinde alt ağaç yeniden
oluşturulur ve bu kez okuma başarılı olur.

```js
// askiya-alma.mjs — hazir olmayan bilesenin en yakin bekleme sinirina sinyal vermesi
const BEKLEME = Symbol("bekleme");

function depo() {
  const kayit = new Map();
  const baslangic = new Map();     // istegin hangi turda baslatildigi
  let tur = 0;
  return {
    turAc: () => { tur++; },
    oku(anahtar) {
      const k = kayit.get(anahtar);
      if (!k) {
        kayit.set(anahtar, { hal: "bekliyor" });
        baslangic.set(anahtar, tur);      // istek ilk okuma denemesinde baslar
        throw BEKLEME;
      }
      if (k.hal === "bekliyor") throw BEKLEME;
      return k.veri;
    },
    yanitla(anahtar, veri) { kayit.set(anahtar, { hal: "hazir", veri }); },
    ozet: () => [...baslangic].map(([a, t]) => `${a}: ${t}. turda`).join(", "),
  };
}

const dugum = (ad, s = {}) => ({ ad, sinir: !!s.sinir, veri: s.veri || null, cocuklar: s.cocuklar || [] });

function olustur(d, kaynak) {
  if (d.sinir) {
    try {
      const p = d.cocuklar.map((c) => olustur(c, kaynak));
      return { metin: `${d.ad}[${p.map((x) => x.metin).join(" ")}]`,
               sayi: 1 + p.reduce((t, x) => t + x.sayi, 0) };
    } catch (h) {
      if (h !== BEKLEME) throw h;
      return { metin: `${d.ad}[YUKLENIYOR]`, sayi: 1 };
    }
  }
  const etiket = d.veri ? `${d.ad}<${kaynak.oku(d.veri)}>` : d.ad;
  if (d.cocuklar.length === 0) return { metin: etiket, sayi: 1 };
  const p = d.cocuklar.map((c) => olustur(c, kaynak));
  return { metin: `${etiket}(${p.map((x) => x.metin).join(" ")})`,
           sayi: 1 + p.reduce((t, x) => t + x.sayi, 0) };
}

const ayriSinirlar = () => dugum("sayfa", { cocuklar: [
  dugum("baslik"),
  dugum("tablo-siniri", { sinir: true, cocuklar: [dugum("olcum-tablosu", { veri: "olcumler" })] }),
  dugum("pano-siniri", { sinir: true, cocuklar: [dugum("karsilastirma-panosu", { veri: "karsilastirma" })] }),
] });

const tekSinir = () => dugum("sayfa", { cocuklar: [
  dugum("baslik"),
  dugum("ortak-sinir", { sinir: true, cocuklar: [
    dugum("olcum-tablosu", { veri: "olcumler" }),
    dugum("karsilastirma-panosu", { veri: "karsilastirma" }),
  ] }),
] });

for (const [ad, kur] of [["iki ayri bekleme siniri", ayriSinirlar], ["tek ortak bekleme siniri", tekSinir]]) {
  console.log(ad + ":");
  const kaynak = depo();
  const turlar = [
    ["ilk olusturma", null],
    ["olcumler geldi", "olcumler"],
    ["karsilastirma geldi", "karsilastirma"],
  ];
  for (const [baslik, gelen] of turlar) {
    kaynak.turAc();
    if (gelen) kaynak.yanitla(gelen, `${gelen} verisi`);
    const s = olustur(kur(), kaynak);
    console.log(`  ${baslik.padEnd(20)} icerik gosteren bilesen: ${s.sayi}`);
    console.log(`    ${s.metin}`);
  }
  console.log(`  istek baslangici -> ${kaynak.ozet()}`);
}
```

```
iki ayri bekleme siniri:
  ilk olusturma        icerik gosteren bilesen: 4
    sayfa(baslik tablo-siniri[YUKLENIYOR] pano-siniri[YUKLENIYOR])
  olcumler geldi       icerik gosteren bilesen: 5
    sayfa(baslik tablo-siniri[olcum-tablosu<olcumler verisi>] pano-siniri[YUKLENIYOR])
  karsilastirma geldi  icerik gosteren bilesen: 6
    sayfa(baslik tablo-siniri[olcum-tablosu<olcumler verisi>] pano-siniri[karsilastirma-panosu<karsilastirma verisi>])
  istek baslangici -> olcumler: 1. turda, karsilastirma: 1. turda
tek ortak bekleme siniri:
  ilk olusturma        icerik gosteren bilesen: 3
    sayfa(baslik ortak-sinir[YUKLENIYOR])
  olcumler geldi       icerik gosteren bilesen: 3
    sayfa(baslik ortak-sinir[YUKLENIYOR])
  karsilastirma geldi  icerik gosteren bilesen: 5
    sayfa(baslik ortak-sinir[olcum-tablosu<olcumler verisi> karsilastirma-panosu<karsilastirma verisi>])
  istek baslangici -> olcumler: 1. turda, karsilastirma: 2. turda
```

Sayfa başlığı her iki yerleşimde de ilk turda görünür: beklemek yalnız veri okuyan alt ağacı
durdurur, kardeşlerini değil. Bu, hata sınırındaki yalıtımın aynısıdır.

## Sınır Yerleşimi ve İstek Şelalesi

İki yerleşim arasındaki fark ikinci turda ortaya çıkar. Ayrı sınırlarda ölçüm tablosu
verisi gelir gelmez görünür; ortak sınırda ekran hiç değişmez, çünkü sınırın altındaki
bütün ağaç hazır olmadıkça yedek görünüm kalkmaz. Bekleme sınırı, "birlikte görünmesi
gereken" parçaları tanımlar.

Çıktının son satırı daha sinsi bir farkı gösterir. Ayrı sınırlarda iki istek de birinci
turda başlamıştır. Ortak sınırda ölçüm tablosunun kesmesi kardeşinin oluşturulmasını
engellediği için karşılaştırma isteği ancak ikinci turda başlar. İkinci istek, birincinin
yanıtını beklemiş olur; iki bağımsız istek ardışıklaşır. Buna **istek şelalesi (request
waterfall)** denir — Tarayıcı ve Web Platformu kursundaki ağ panelinde bu, basamaklı bir
şelale görünümü olarak okunur.

Şelalenin ikinci ve daha yaygın biçimi iç içe bileşenlerde ortaya çıkar: üst bileşen
istasyon kaydını okur, alt bileşen o kayıttaki kimlikle ölçümleri okur. İkinci istek
gerçekten birinciye bağlıdır ve yerleşimle çözülmez. Çözüm, isteği oluşturmanın başlatmasını
beklememektir: veri isteği yönlendirme çözümlendiği anda başlatılır, bileşen oluşturulduğunda
istek çoktan yoldadır. Kural şudur: **veri gereksinimi, oluşturmadan önce bilinebiliyorsa
istek oluşturmadan önce başlatılır.**

## Gösterge Titremesi

Bekleme görünümünün ne zaman gösterileceği ayrı bir karardır ve ölçülebilir.

```js
// gosterge.mjs — yukleniyor gostergesinin ne zaman cikacagi ve ne kadar kalacagi
const YANITLAR = [80, 150, 220, 900];   // ms cinsinden yanit sureleri
const ESIK = 200;    // bu sureden once gelen yanitta gosterge hic cikmaz
const EN_AZ = 400;   // gosterge ciktiysa en az bu kadar ekranda kalir

function hesapla(politika, yanit) {
  if (politika === "hemen") return { baslar: 0, biter: yanit, icerik: yanit };
  if (yanit <= ESIK) return { baslar: null, biter: null, icerik: yanit };
  if (politika === "gecikmeli") return { baslar: ESIK, biter: yanit, icerik: yanit };
  const biter = Math.max(yanit, ESIK + EN_AZ);      // gecikmeli + en az sure
  return { baslar: ESIK, biter, icerik: biter };
}

for (const politika of ["hemen", "gecikmeli", "gecikmeli+en az"]) {
  console.log(`${politika}:`);
  for (const yanit of YANITLAR) {
    const s = hesapla(politika, yanit);
    const sure = s.baslar === null ? 0 : s.biter - s.baslar;
    const satir = [
      `  yanit ${String(yanit).padStart(3)} ms ->`,
      `gosterge ${s.baslar === null ? "cikmaz" : `${s.baslar}-${s.biter} ms`}`.padEnd(20),
      `gorunme suresi ${String(sure).padStart(3)} ms`,
      `| icerik ${String(s.icerik).padStart(3)} ms'de`,
    ].join(" ");
    console.log(sure > 0 && sure < 300 ? `${satir}  <- titreme` : satir);
  }
}
```

```
hemen:
  yanit  80 ms -> gosterge 0-80 ms     gorunme suresi  80 ms | icerik  80 ms'de  <- titreme
  yanit 150 ms -> gosterge 0-150 ms    gorunme suresi 150 ms | icerik 150 ms'de  <- titreme
  yanit 220 ms -> gosterge 0-220 ms    gorunme suresi 220 ms | icerik 220 ms'de  <- titreme
  yanit 900 ms -> gosterge 0-900 ms    gorunme suresi 900 ms | icerik 900 ms'de
gecikmeli:
  yanit  80 ms -> gosterge cikmaz      gorunme suresi   0 ms | icerik  80 ms'de
  yanit 150 ms -> gosterge cikmaz      gorunme suresi   0 ms | icerik 150 ms'de
  yanit 220 ms -> gosterge 200-220 ms  gorunme suresi  20 ms | icerik 220 ms'de  <- titreme
  yanit 900 ms -> gosterge 200-900 ms  gorunme suresi 700 ms | icerik 900 ms'de
gecikmeli+en az:
  yanit  80 ms -> gosterge cikmaz      gorunme suresi   0 ms | icerik  80 ms'de
  yanit 150 ms -> gosterge cikmaz      gorunme suresi   0 ms | icerik 150 ms'de
  yanit 220 ms -> gosterge 200-600 ms  gorunme suresi 400 ms | icerik 600 ms'de
  yanit 900 ms -> gosterge 200-900 ms  gorunme suresi 700 ms | icerik 900 ms'de
```

Göstergeyi hemen göstermek, hızlı yanıtlarda ekranda beliren ve hemen kaybolan bir kare
üretir. Kullanıcı bunu bir yükleme olarak değil bir sıçrama olarak algılar; iki durum
değişimi, tek bir bekleme görünmesinden daha rahatsız edicidir.

Gecikmeli gösterim eşiğin altındaki yanıtlarda göstergeyi hiç çıkarmaz. Ne var ki eşiğin
hemen üstündeki yanıtta yirmi milisaniyelik bir titreme bırakır — sorunun en kötü biçimi.

Üçüncü politika bunu en az gösterim süresiyle kapatır ve bedelini görünür kılar: iki yüz
yirmi milisaniyede hazır olan içerik altı yüz milisaniyeye kadar bekletilir. Bu, bilinçli
olarak ödenen bir gecikmedir; hızlı yanıtın ödülünü kullanıcıya vermez, karşılığında
sarsıntısız bir ekran verir. Üç politika arasındaki seçim ölçülen yanıt dağılımına bağlıdır:
yanıtların çoğu eşiğin altındaysa ikinci, eşiğin çevresinde toplanıyorsa üçüncü politika
seçilir.

## Bekleme Görünümünün Tasarımı ve Geçişler

Bekleme görünümünün geleceği içeriğin yerini tutması gerekir. Dönen bir gösterge, yerini
alacağı tablodan küçükse veri geldiğinde sayfa aşağı kayar; Web'in Temelleri ve HTML
kursunda tanımlanan **içerik kaymasıdır** bu. Bunun yerine gelecek düzenin ölçülerini
taşıyan bir iskelet görünüm konur: aynı satır sayısı, aynı sütun genişlikleri, aynı yükseklik.

İkinci karar geçişlerdedir. İlk yükleme ile sonraki yükleme farklı sorunlardır. Kullanıcı
süzgeci değiştirdiğinde ekranda çalışan bir tablo vardır; yedek görünüme düşmek bu tabloyu
silip iskelete dönmek olur. Çalışan bir ekranı boşaltmak, kullanıcının bağlamını da siler.

Daha iyi davranış, eski içeriği yerinde tutup bir bekleme göstergesi eklemektir — solmuş
bir tablo, başlıkta küçük bir gösterge, devre dışı bırakılmış bir süzgeç. Kural şöyle
yazılabilir: **bekleme sınırı boş bir alanı doldurmak içindir; dolu bir alanı boşaltmak
için değil.** Eski içerik gösterilirken onun eski olduğunun belirtilmesi gerekir, yoksa
kullanıcı güncellenmiş veri gördüğünü sanır.

Erişilebilirlik tarafı da atlanmaz. Bekleme ve tamamlanma, ekran okuyucuya duyurulmalıdır;
görsel bir göstergenin tek başına anlamı yoktur. Devre dışı bırakılan denetimlerin nedeni de
metinle bildirilir.

## Özet

- Her bileşende ayrı tutulan veri, yükleniyor ve hata bayrakları sekiz bileşim üretir ve
  bunların beşi geçersizdir.
- Askıya alma, verisi hazır olmayan bileşenin oluşturmayı kesip yukarıya sinyal vermesidir;
  en yakın bekleme sınırı sinyali yakalar, alt ağacın yerine bekleme görünümü koyar ve
  kardeş alt ağaçlar oluşturulmayı sürdürür.
- Bekleme sınırı, birlikte görünmesi gereken parçaları tanımlar; tek bir sınırın altında
  toplanan bağımsız istekler ardışıklaşarak istek şelalesi üretir.
- Veri gereksinimi oluşturmadan önce bilinebiliyorsa istek oluşturmadan önce başlatılır.
- Göstergeyi hemen göstermek titreme üretir; eşikli gösterim kısa yanıtlarda göstergeyi
  eler, en az gösterim süresi titremeyi kapatır ama içeriği geciktirir.
- Bekleme görünümü gelecek içeriğin ölçülerini taşımalıdır; süzgeç değişimi gibi
  geçişlerde çalışan içerik silinmez, eski olduğu belirtilerek korunur.

## Sonraki Adım

Buraya kadarki yedi ders bir alt ağacın **ne zaman** oluşturulacağını belirledi: durum
değiştiğinde, bağımlılık değiştiğinde, hata yakalandığında, veri geldiğinde. Bir soru daha
kaldı ve o zamanla değil yerle ilgili: alt ağaç **nereye** çizilir?

Varsayılan yanıt açıktır — bileşen ağacındaki yeri, belge ağacındaki yerini belirler. Ölçüm
istasyonu sayfasında bu varsayılanın kırıldığı bir nokta vardır. Süzgeç panelindeki açılır
liste, panelin kendi kutusundan taşar; kabın kırpması listeyi keser, kabın yığılma bağlamı
listeyi tablonun altında bırakır. Bileşen mantıksal olarak panelin içindedir ama görsel
olarak sayfanın en üstünde çizilmelidir. Sonraki ders bu ayrılığı, iki ağacın birbirinden
bağımsız hale gelmesini ve bunun olay yayılımıyla erişilebilirliğe ne yaptığını ele alır.
