---
title: Zamanlayıcılar
source: 'https://academia.sh/tr/kurslar/eszamansiz-javascript/zamanlayicilar'
course: 'Eşzamansız JavaScript ve Çalışma Zamanı'
language: tr
updated: '2026-08-17T18:09:44+00:00'
license: 'CC BY-SA 4.0'
---

# Zamanlayıcılar

Gecikmenin alt sınır oluşu, eşit gecikmeli zamanlayıcıların sırası, yinelemeli çalıştırmada kayma ve üst üste binme, kendi kendini zamanlayan döngü ve iptal.

Önceki ders, kuyruğa iş koyan çağrıların yalnız kayıt yaptığını gösterdi. En sık
kullanılan kayıt aracı zamanlayıcılardır ve verilen sayı çoğu zaman yanlış okunur:
`setTimeout(f, 10)` çağrısı, `f`'nin on milisaniye sonra çalışacağını söylemez.

Bu ders o sayının ne söylediğini, eşit gecikmeli zamanlayıcıların hangi sıraya girdiğini
ve yinelemeli çalıştırmanın nerede kaydığını kurar. Ölçüm akışının ilk çalışan parçası da
burada, zamanlayıcıya dayalı sahte bir istasyon olarak ortaya çıkacak.

## Gecikme Bir Alt Sınırdır

`setTimeout(geriCagri, gecikme)` çağrısının anlamı şudur: *geçen süre `gecikme` değerine
ulaşmadan geri çağrı kuyruğa alınmaz.* Kuyruğa alındıktan sonra ne zaman çalışacağı,
önündeki işlerin ne kadar süreceğine bağlıdır.

Aynı anda kaydedilen zamanlayıcılar, gecikmelerine göre sıraya girer; gecikmeleri eşitse
kaydedilme sıralarını korurlar.

```js
setTimeout(() => console.log("4 — 20 ms"), 20);
setTimeout(() => console.log("3 — 10 ms"), 10);
setTimeout(() => console.log("1 — 0 ms, ilk kayıt"), 0);
setTimeout(() => console.log("2 — 0 ms, ikinci kayıt"), 0);
```

```
1 — 0 ms, ilk kayıt
2 — 0 ms, ikinci kayıt
3 — 10 ms
4 — 20 ms
```

Sıfır gecikme "hemen" anlamına gelmez, "en erken fırsatta" anlamına gelir. Ana ortamlar
ayrıca bir taban gecikme uygular: HTML standardı, beşten derin iç içe geçmiş
zamanlayıcılarda alt sınırı dört milisaniyeye çıkarır; sunucu çalışma zamanlarında da
sıfır gecikme genellikle bir milisaniyeye yuvarlanır. Sayı ne olursa olsun, alt sınırdan
öteye söz verilmez.

## Engelleme Alt Sınırı Aşar

Alt sınırın üst sınırı yoktur. Önceki turdaki iş uzun sürerse, süresi çoktan dolmuş bir
zamanlayıcı kuyrukta bekler.

```js
function meshgulBekle(sure) {
  const bitis = Date.now() + sure;
  while (Date.now() < bitis) {
    // İş parçacığını kasten meşgul tutar.
  }
}

setTimeout(() => {
  console.log("1 — 10 ms zamanlayıcısı; 50 ms boyunca iş parçacığını tutuyor");
  meshgulBekle(50);
  console.log("2 — 10 ms zamanlayıcısı bitti");
}, 10);

setTimeout(() => console.log("3 — 20 ms zamanlayıcısı"), 20);
```

```
1 — 10 ms zamanlayıcısı; 50 ms boyunca iş parçacığını tutuyor
2 — 10 ms zamanlayıcısı bitti
3 — 20 ms zamanlayıcısı
```

İkinci zamanlayıcının süresi, birinci geri çağrı hâlâ çalışırken doldu. Sonuna kadar
çalışma kuralı gereği araya giremedi; birinci iş bitene kadar bekledi. Bu, ölçülen
gecikmenin neden istenen gecikmeden büyük olabildiğinin tek nedenidir: iş parçacığı meşgul.

## Yinelemeli Çalıştırma ve Üst Üste Binme

`setInterval(geriCagri, aralik)`, geri çağrıyı belirli aralıklarla kuyruğa koyar. Aralık,
*geri çağrının bitişinden sonraki* değil, *kaydedilme anlarındaki* sürelerle ölçülür. Geri
çağrı aralıktan uzun sürerse, ardışık çalıştırmalar arasında boşluk kalmaz.

Aşağıdaki iki program yalnız tek satırla ayrılır. Birincisinde geri çağrı kısa:

```js
let tik = 0;
const kimlik = setInterval(() => {
  tik += 1;
  console.log("aralık tiki", tik);
  if (tik === 3) clearInterval(kimlik);
}, 5);

setTimeout(() => console.log("30 ms zamanlayıcısı"), 30);
```

```
aralık tiki 1
aralık tiki 2
aralık tiki 3
30 ms zamanlayıcısı
```

Üç tik beşer milisaniyelik aralıklarla tamamlandı ve otuzuncu milisaniyedeki zamanlayıcı
sıraya girdi. İkincisinde ise her tik yirmi milisaniye iş yapıyor:

```js
function meshgulBekle(sure) {
  const bitis = Date.now() + sure;
  while (Date.now() < bitis) {
    // İş parçacığını kasten meşgul tutar.
  }
}

let tik = 0;
const kimlik = setInterval(() => {
  tik += 1;
  console.log("aralık tiki", tik);
  meshgulBekle(20);
  if (tik === 3) clearInterval(kimlik);
}, 5);

setTimeout(() => console.log("30 ms zamanlayıcısı"), 30);
```

```
aralık tiki 1
aralık tiki 2
30 ms zamanlayıcısı
aralık tiki 3
```

Sıra değişti. İkinci tik, otuzuncu milisaniye gelmeden başladı ve yirmi milisaniye
boyunca iş parçacığını tuttu; zamanlayıcı ancak o iş bittikten sonra çalışabildi. Üçüncü
tik ise arkasından, neredeyse ara vermeden geldi.

Bu davranışın iki sonucu vardır. Birincisi, `setInterval` ile kurulan bir akışta geri
çağrılar arasında dinlenme süresi güvence altında değildir. İkincisi, geri çağrı içinde
eşzamansız iş başlatılıyorsa, önceki çalıştırma bitmeden yenisi başlayabilir ve iki iş
üst üste biner.

## Kendi Kendini Zamanlayan Döngü

Her çalıştırma arasında en az bir aralık boşluk isteniyorsa, yineleme `setTimeout` ile
kurulur: geri çağrı işini bitirdikten sonra bir sonrakini kendisi kaydeder.

Bu kalıp, ölçüm akışının ilk çalışan biçimidir. Sahte istasyonlar, gecikmeleri ve
değerleri sabit bir tablodan okunur; böylece program her çalıştırmada aynı çıktıyı verir.

```js
const KAYNAK = {
  A1: { gecikme: 30, deger: 21.4 },
  B2: { gecikme: 10, deger: 19.8 },
  C3: { gecikme: 20, deger: 23.1 },
};

function akisBasla(istasyonlar, aralik, gericagri) {
  let sayac = 0;
  let kimlik = null;
  let durduruldu = false;

  function tur() {
    const istasyon = istasyonlar[sayac % istasyonlar.length];
    sayac += 1;
    gericagri({ sira: sayac, istasyon, deger: KAYNAK[istasyon].deger });
    if (!durduruldu) kimlik = setTimeout(tur, aralik);
  }

  kimlik = setTimeout(tur, aralik);

  return function durdur() {
    durduruldu = true;
    clearTimeout(kimlik);
  };
}

const durdur = akisBasla(["A1", "B2", "C3"], 5, (olcum) => {
  console.log(olcum.sira, olcum.istasyon, olcum.deger);
  if (olcum.sira === 4) durdur();
});
```

```
1 A1 21.4
2 B2 19.8
3 C3 23.1
4 A1 21.4
```

`durduruldu` bayrağı gereksiz görünebilir; değildir. `durdur` işlevi, geri çağrının
*içinden* çağrılır ve o sırada bir sonraki tur henüz kaydedilmemiştir. Yalnız
`clearTimeout` çağrılsaydı, çağrı zaten çalışmış bir zamanlayıcıyı iptal eder, hemen
ardından `tur` yeni bir zamanlayıcı kaydederdi ve akış hiç durmazdı. Kendi kendini
zamanlayan döngülerde iptal, bir durum bayrağıyla birlikte kurulmalıdır.

## Bekleyen Zamanlayıcı Programı Ayakta Tutar

Bekleyen bir zamanlayıcı, ana ortam için "yapılacak iş var" demektir. Sunucu çalışma
zamanı, bekleyen iş kalmayana kadar kapanmaz.

```js
process.on("exit", () => console.log("3 — çalışma zamanı kapanıyor"));

setTimeout(() => console.log("2 — bekleyen zamanlayıcı çalıştı"), 50);
console.log("1 — betiğin eşzamanlı kısmı bitti");
```

```
1 — betiğin eşzamanlı kısmı bitti
2 — bekleyen zamanlayıcı çalıştı
3 — çalışma zamanı kapanıyor
```

Aynı program `clearTimeout` ile iptal edilirse, kapanış hemen gerçekleşir:

```js
process.on("exit", () => console.log("2 — çalışma zamanı kapanıyor"));

const kimlik = setTimeout(() => console.log("bu satır hiç çalışmaz"), 50);
clearTimeout(kimlik);
console.log("1 — betiğin eşzamanlı kısmı bitti");
```

```
1 — betiğin eşzamanlı kısmı bitti
2 — çalışma zamanı kapanıyor
```

Bu gözlem ileride iki yerde işe yarayacak: iptal edilmemiş bir zamanlayıcı hem programın
kapanmasını geciktirir hem de geri çağrısının kapattığı bütün değerleri bellekte tutar.
İkincisi bellek konusunda ele alınacak sızıntı türlerinden biridir.

## Zamanlayıcı Ne Değildir

Üç yaygın yanlış okuma vardır ve üçü de aynı kaynaktan çıkar.

`setTimeout(f, 0)` "hemen çalıştır" değildir; "yığıt boşalınca çalıştır" demektir. Bu
nedenle uzun bir işi ikiye bölmek için kullanılabilir, ama işi hızlandırmaz.

Zamanlayıcı bir kronometre değildir. Geri çağrı içinde geçen süreyi ölçmek için
zamanlayıcı gecikmesine güvenilemez; ölçüm ayrı bir araçla yapılır.

Zamanlayıcı bir eşzamanlılık aracı da değildir. İki geri çağrı asla aynı anda çalışmaz;
biri bitmeden diğeri başlamaz. Beklemeler üst üste biner, hesaplar binmez.

## Özet

- Zamanlayıcı gecikmesi bir alt sınırdır; üst sınır yoktur ve meşgul iş parçacığı bu
  sınırı serbestçe aşar.
- Eşit gecikmeli zamanlayıcılar kaydedilme sıralarını korur.
- `setInterval` çalıştırmalar arasında boşluk güvencesi vermez; uzun süren geri çağrılarda
  tikler üst üste biner.
- Kendi kendini zamanlayan `setTimeout` döngüsü her tur arasında en az bir aralık bırakır;
  iptali için durum bayrağı gerekir.
- Bekleyen bir zamanlayıcı çalışma zamanını ayakta tutar ve geri çağrısının kapattığı
  değerleri bellekte tutar.

## Sonraki Adım

Zamanlayıcılar geri çağrıyı zamana bağladı; sıradaki adım geri çağrıyı *sonuca* bağlamak.
Sonraki ders, ölçüm kaynağını hata bildirebilen bir geri çağrı arayüzüne dönüştürür; üç
istasyonu sırayla ve birlikte okumayı dener; ardından bu yaklaşımın sınırlarını gösterir:
iç içe geçme, hata yollarının tekrarı ve geri çağrıyı çağıran tarafa bırakmanın getirdiği
belirsizlikler. Sözler bu sınırların yanıtı olarak doğacak.
