---
title: 'Yükleme ve Hata Durumları'
source: 'https://academia.sh/tr/kurslar/frontend-mimarisi/yukleme-ve-hata-durumlari'
course: 'Uygulama Mimarisi: Yönlendirme, Durum ve Veri'
language: tr
updated: '2026-08-17T18:09:20+00:00'
license: 'CC BY-SA 4.0'
---

# Yükleme ve Hata Durumları

Görünümün veri beklerken bulunabileceği durumların sayılı bir kümeye indirgenmesi; mantıksal bayrakların ürettiği çelişkiler, geçiş tablosu, yarış koşullarının damgayla elenmesi ve durumların ekrana karşılığı.

Önceki üç ders veriyi almanın yollarını kurdu. Hepsinin ortak yanı, verinin bir süre henüz
gelmemiş olmasıdır. Ölçüm geçmişi ekranı o sırada boş duramaz: bir şey göstermek zorunda.
Gösterilecek şey, ekranın **o an hangi durumda olduğuna** bağlıdır — ilk kez mi yükleniyor,
elde eski veri var mı, istek başarısız mı oldu, sonuç boş mu döndü.

Bu ders o durumları sayılı bir kümeye indirger. İndirgeme bir düzen kaygısı değil: aşağıda
görüleceği gibi, durumları ayrı ayrı mantıksal bayraklarla tutmak birbiriyle çelişen
bileşimler üretir ve bu bileşimler ekranda gerçek kusur olarak görünür.

## Mantıksal Bayrakların Ürettiği Çelişki

En sık başlanan yol üç bayraktır: `yukleniyor`, `hata`, `veri`. Üç mantıksal değerin
sekiz bileşimi vardır. Bunların yalnız dördü anlamlıdır.

- Yükleniyor doğru, veri boş, hata yok — ilk yükleme. Anlamlı.
- Yükleniyor yanlış, veri dolu, hata yok — hazır. Anlamlı.
- Yükleniyor yanlış, veri boş, hata var — başarısız. Anlamlı.
- Yükleniyor doğru, veri dolu, hata yok — tazeleme. Anlamlı.
- Yükleniyor doğru, hata var — istek sürüyor ama hata gösteriliyor. Ekranda dönen bir
  yükleme göstergesiyle bir hata kutusu yan yana durur.
- Yükleniyor yanlış, veri boş, hata yok — hiçbir şey söylemez. Ekran boştur; kullanıcı
  isteğin başlamadığını mı, bittiğini ve sonuç bulunmadığını mı bilemez.
- Veri dolu, hata var — hangisi gösterilecek? Bu karar her bileşende yeniden verilir ve
  farklı verilir.

Bayrakların sorunu, **birbirinden bağımsız değişebilmeleridir**. Yeni bir istek başlarken
eski hatayı temizlemeyi unutan tek bir satır, beşinci bileşimi üretir. Kusur derleme
zamanında görünmez, yalnız belirli bir tıklama sırasında ortaya çıkar.

Çözüm, üç bayrağı tek bir alanla değiştirmektir: görünüm aynı anda tek bir durumdadır ve
durumlar arasında yalnız tanımlı geçişler vardır. Geçersiz bileşim böylece
temsil edilemez hâle gelir.

## Yedi Durum ve Geçiş Tablosu

Veri çeken bir ekranın ihtiyaç duyduğu durumlar şunlardır: **boş** (henüz istenmedi),
**yükleniyor** (elde veri yokken bekleniyor), **hazır** (veri var), **boş sonuç** (istek
başarılı, sonuç kümesi boş), **yenileniyor** (elde veri varken tazeleniyor), **hata**
(elde veri yok, istek başarısız) ve **bayat** (elde eski veri var, tazeleme başarısız).

Son iki durumun ayrılması bu tasarımın özüdür. Elde gösterilecek veri varken tazeleme
başarısız olduğunda ekranı hata kutusuna çevirmek, kullanıcının elindeki bilgiyi almak
demektir. Bayat durumu eski veriyi ekranda tutar ve tazelemenin başarısız olduğunu ayrı
bir bildirimle söyler.

```js
// gorunum-durumu.mjs — gorunum durum makinesi ve gecis tablosu
const DURUMLAR = ["bos", "yukleniyor", "hazir", "bosSonuc", "yenileniyor", "hata", "bayat"];
const OLAYLAR = ["iste", "doluGeldi", "bosGeldi", "basarisiz", "iptal"];

// Veriye bagli hedefler islev olarak yazilir.
const doluysaHazir = (b) => (b.veri.length > 0 ? "hazir" : "bosSonuc");

const TABLO = {
  bos:         { iste: "yukleniyor" },
  yukleniyor:  { doluGeldi: "hazir", bosGeldi: "bosSonuc", basarisiz: "hata", iptal: "bos" },
  hazir:       { iste: "yenileniyor" },
  bosSonuc:    { iste: "yenileniyor" },
  yenileniyor: { doluGeldi: "hazir", bosGeldi: "bosSonuc", basarisiz: "bayat", iptal: doluysaHazir },
  hata:        { iste: "yukleniyor" },
  bayat:       { iste: "yenileniyor" },
};

function gecis(birim, olay, yuk = null) {
  const hedef = TABLO[birim.durum]?.[olay];
  if (hedef === undefined) return { ...birim, yoksayilan: birim.yoksayilan + 1 };
  const yeni = { ...birim };
  if (olay === "doluGeldi") yeni.veri = yuk;
  if (olay === "bosGeldi") yeni.veri = [];
  if (olay === "basarisiz") yeni.hata = yuk;
  if (olay === "doluGeldi" || olay === "bosGeldi") yeni.hata = null;
  yeni.durum = typeof hedef === "function" ? hedef(yeni) : hedef;
  return yeni;
}

// --- Gecis tablosunun yazdirilmasi -----------------------------------------
const hucre = (d, o) => {
  const h = TABLO[d]?.[o];
  return h === undefined ? "·" : typeof h === "function" ? "veriye bağlı" : h;
};
console.log("durum".padEnd(12) + OLAYLAR.map((o) => o.padEnd(13)).join(""));
for (const d of DURUMLAR) {
  console.log(d.padEnd(12) + OLAYLAR.map((o) => hucre(d, o).padEnd(13)).join(""));
}

// --- Dizilerin sinanmasi ----------------------------------------------------
const OLCUM = [{ kimlik: "o-114", deger: -4.2 }];
const DIZILER = [
  ["ilk yükleme başarılı", [["iste"], ["doluGeldi", OLCUM]]],
  ["ilk yükleme boş",      [["iste"], ["bosGeldi"]]],
  ["ilk yükleme hatalı",   [["iste"], ["basarisiz", "ag"]]],
  ["hatadan sonra tekrar", [["iste"], ["basarisiz", "ag"], ["iste"], ["doluGeldi", OLCUM]]],
  ["tazeleme hatası",      [["iste"], ["doluGeldi", OLCUM], ["iste"], ["basarisiz", "sunucu"]]],
  ["tazeleme iptali",      [["iste"], ["doluGeldi", OLCUM], ["iste"], ["iptal"]]],
  ["geçersiz sıra",        [["doluGeldi", OLCUM], ["iptal"], ["iste"]]],
];

console.log("");
for (const [ad, olaylar] of DIZILER) {
  let birim = { durum: "bos", veri: [], hata: null, yoksayilan: 0 };
  const iz = ["bos"];
  for (const [olay, yuk] of olaylar) {
    birim = gecis(birim, olay, yuk);
    iz.push(birim.durum);
  }
  console.log(
    ad.padEnd(22), iz.join(" → ").padEnd(46),
    `veri=${birim.veri.length} hata=${birim.hata} yoksayılan=${birim.yoksayilan}`);
}

// --- Yaris korumasi: gec gelen yanit yok sayilir ---------------------------
console.log("");
let birim = { durum: "bos", veri: [], hata: null, yoksayilan: 0 };
let damga = 0;
const istek = () => { damga += 1; birim = gecis(birim, "iste"); return damga; };
const yanit = (kendiDamgasi, olay, yuk) => {
  if (kendiDamgasi !== damga) { console.log(`  damga ${kendiDamgasi}: eskimiş, yok sayıldı`); return; }
  birim = gecis(birim, olay, yuk);
  console.log(`  damga ${kendiDamgasi}: uygulandı → ${birim.durum}`);
};

const d1 = istek();                       // "kuz" icin arama
const d2 = istek();                       // "kuzey" icin arama
yanit(d2, "doluGeldi", [{ kimlik: "o-114" }, { kimlik: "o-113" }]);
yanit(d1, "doluGeldi", [{ kimlik: "o-001" }]);   // gec gelen eski yanit
console.log("son durum:", birim.durum, "| kayıt:", birim.veri.length);
```

```
durum       iste         doluGeldi    bosGeldi     basarisiz    iptal        
bos         yukleniyor   ·            ·            ·            ·            
yukleniyor  ·            hazir        bosSonuc     hata         bos          
hazir       yenileniyor  ·            ·            ·            ·            
bosSonuc    yenileniyor  ·            ·            ·            ·            
yenileniyor ·            hazir        bosSonuc     bayat        veriye bağlı 
hata        yukleniyor   ·            ·            ·            ·            
bayat       yenileniyor  ·            ·            ·            ·            

ilk yükleme başarılı   bos → yukleniyor → hazir                       veri=1 hata=null yoksayılan=0
ilk yükleme boş        bos → yukleniyor → bosSonuc                    veri=0 hata=null yoksayılan=0
ilk yükleme hatalı     bos → yukleniyor → hata                        veri=0 hata=ag yoksayılan=0
hatadan sonra tekrar   bos → yukleniyor → hata → yukleniyor → hazir   veri=1 hata=null yoksayılan=0
tazeleme hatası        bos → yukleniyor → hazir → yenileniyor → bayat veri=1 hata=sunucu yoksayılan=0
tazeleme iptali        bos → yukleniyor → hazir → yenileniyor → hazir veri=1 hata=null yoksayılan=0
geçersiz sıra          bos → bos → bos → yukleniyor                   veri=0 hata=null yoksayılan=2

  damga 2: uygulandı → hazir
  damga 1: eskimiş, yok sayıldı
son durum: hazir | kayıt: 2
```

## Tablodan Okunanlar

Tablodaki nokta işaretleri **tanımsız geçişleri** gösterir ve asıl bilgi oradadır.
`hazir` durumundayken `basarisiz` olayı gelemez, çünkü hazır durumdayken uçuşta bir istek
yoktur. Bu, kodun bir yerinde açıkça yasaklanmış bir kural değil; tablonun boş bıraktığı
bir hücre. Yedinci dizi bunu sınıyor: istek atılmadan gelen yanıt ve iptal olayları yok
sayıldı, sayaç ikiyi gösterdi. Bayrak tabanlı bir gerçekleştirimde aynı iki olay durumu
sessizce bozardı.

Beşinci ve altıncı diziler `yenileniyor` durumunun iki farklı çıkışını gösteriyor.
Başarısızlıkta `bayat`a geçildi ve `veri=1` korundu — eski ölçüm listesi ekranda kaldı.
İptalde `hazir`a dönüldü ve hata alanı boş kaldı; önceki dersin kuralı burada işliyor,
iptal bir hata değildir.

Dördüncü dizi hata sonrası kurtarmayı gösteriyor. `hata` durumundan yalnız `iste` çıkar;
"tekrar dene" düğmesinin karşılığı budur. Yeni istek başlarken hata alanının temizlenmesi
geçiş işlevinin içinde tek bir yerde yapılır, her çağrı noktasında değil.

Durum makinesinin yan faydası sınanabilirliktir. Yukarıdaki yedi dizi bir birim testi
kümesidir; ekran hiç çizilmeden görünümün davranışı doğrulanabilir. Bileşenin içine
serpiştirilmiş bayraklarda bu ayrıştırma mümkün değildir.

## Yarış Koşulu ve Damga

Son bölüm, REST İstemcisi dersinde bırakılan sorunun görünüm tarafındaki yarısını
kapatıyor. Kullanıcı istasyon süzgecine "kuz" yazdı, sonra "kuzey" yazdı; iki istek yola
çıktı. İkinci istek daha önce yanıtlandı, birincisi geç geldi. Geç gelen yanıt uygulanırsa
ekranda "kuz" sonuçları görünür ama süzgeç kutusunda "kuzey" yazar.

Çözüm bir **istek damgasıdır**: her yeni istek bir sayaç artırır ve kendi damgasını taşır.
Yanıt geldiğinde damga, o an geçerli olan damgayla karşılaştırılır; eşleşmiyorsa yanıt
uygulanmaz. Çıktının son üç satırı bunu gösteriyor: ikinci istek uygulandı, birincisi
eskimiş sayıldı, ekranda iki kayıt kaldı.

Damga, isteğin iptal edilmesinin yerine geçmez; ikisi birlikte kullanılır. İptal ağ
kaynağını serbest bırakır ama iptal edilemeyen bir isteğin — örneğin yanıtı zaten
yola çıkmış bir isteğin — geç gelmesini engellemez. Damga, o son savunmadır.

Aynı düzenek anahtar bazında da kurulabilir: sayaç yerine "hangi süzgeç için" bilgisi
saklanır ve gelen yanıt kendi anahtarıyla eşleşmiyorsa atılır. Sunucu durumu yönetiminde
önbellek anahtarı zaten bu işi görür; damga, önbellek kullanmayan ekranlar için aynı
korumayı sağlar.

## Durumların Ekrana Karşılığı

Durum kümesi belirlendikten sonra her durumun görsel karşılığı ayrı bir karardır. Arayüz
Tasarımının Temelleri kursundaki Yükleme ve Boş Durumlar ile Hata ve Uyarı Durumları
dersleri bu kararların ölçütlerini kurar; burada yalnız durum makinesine bağlanan yanları
anılır.

**Yükleniyor** durumunda gösterilecek şey, beklenen içeriğin biçimine bağlıdır. Yapısı
bilinen bir liste için yer tutucu bir iskelet, gelen içeriğin kaplayacağı alanı önceden
ayırır ve içerik geldiğinde kayma oluşmaz. Yapısı bilinmeyen bir sonuç için nötr bir
gösterge yeterlidir.

**Yenileniyor** durumu, `yukleniyor` ile aynı görünmemelidir. Elde veri varken ekranı
iskelete çevirmek, kullanıcının okuduğu içeriği ondan almaktır. Doğru sunum, mevcut
içeriği yerinde bırakıp tazelemeyi küçük ve kenarda bir göstergeyle bildirmektir.

**Boş sonuç** ile **hata** ayrı iletiler ister. Boş sonuç sistemin doğru çalıştığını ve
ölçütü karşılayan kayıt bulunmadığını söyler; kurtarma yolu ölçütü değiştirmektir. Hata,
sistemin yanıt veremediğini söyler; kurtarma yolu tekrar denemektir. İkisini aynı kutuda
sunmak, kullanıcıyı yanlış eyleme yönlendirir.

**Bayat** durumu iki bilgiyi aynı anda taşır: ekrandaki veri geçerlidir ama güncel
olmayabilir. Sunumu, veriyi yerinde bırakıp üstünde tazelemenin başarısız olduğunu ve son
başarılı güncellemenin ne zaman yapıldığını bildiren bir şeritle yapılır. "Tekrar dene"
eylemi bu şeritte durur.

Bir de sürenin kendisi bir karardır. Yanıt çok hızlı geldiğinde yükleme göstergesini
göstermek, ekranda anlık bir titreme üretir; gösterge küçük bir gecikmeden sonra
görünecek biçimde ertelenir. Gösterge bir kez göründüyse de en az kısa bir süre ekranda
kalır, yoksa aynı titreme çıkışta yaşanır. Bu iki eşik durum makinesinin dışındadır:
makine `yukleniyor` der, göstergeyi ne zaman çizeceğine sunum katmanı karar verir.

## Özet

- Yükleme, hata ve veri bilgisini ayrı mantıksal bayraklarla tutmak sekiz bileşim üretir;
  yarısı çelişkilidir ve bu çelişkiler ekranda gerçek kusur olarak görünür.
- Tek alanlı bir durum makinesi geçersiz bileşimleri temsil edilemez kılar; tablodaki boş
  hücreler tanımsız geçişleri gösterir ve beklenmeyen olay sessizce yok sayılır.
- Elde veri varken tazelemenin başarısız olması ayrı bir durumdur; ekranı hata kutusuna
  çevirmek yerine eski veri korunur ve tazeleme başarısızlığı ayrıca bildirilir.
- Boş sonuç ile hata farklı kurtarma yolları önerir: biri ölçütü değiştirmeyi, diğeri
  tekrar denemeyi.
- İstek damgası geç gelen yanıtı eler; iptalin yerine geçmez, onunla birlikte çalışır.
- Yükleme göstergesinin görünme ve en az kalma eşikleri sunum katmanının kararıdır; durum
  makinesi yalnız hangi durumda olunduğunu söyler.

## Sonraki Adım

Durum makinesi `basarisiz` olayını tek bir kapı olarak ele aldı: hata geldi, duruma
geçildi, kullanıcıya "tekrar dene" düğmesi sunuldu. Oysa hataların bir kısmı kullanıcıya
hiç gösterilmemeli. Zayıf bir bağlantıda kesilen bir istek, iki yüz milisaniye sonra
yeniden denendiğinde başarılı olabilir; kullanıcı arada hiçbir şey görmez. Hangi hatanın
kendiliğinden yeniden deneneceği, denemeler arasında ne kadar bekleneceği ve bu beklemenin
neden rastgeleleştirilmesi gerektiği sonraki dersin konusudur.
