Menu

TypeScript Sleep: TypeScript'te Bekleme ve Gecikme

TypeScript'te yerleşik bir sleep yoktur, ama tek bir satır size bir tane verir: setTimeout ile resolve olan bir Promise<void> döndüren bir fonksiyon. Onu await etmeyi, döngü içinde duraklamayı, gecikmeyle yeniden denemeyi, bir sleep'i iptal etmeyi ve JavaScript'te neden bloklayan bir sleep olmadığını öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

TypeScript'te yerleşik bir sleep yoktur. Gecikmeden sonra setTimeout'un resolve ettiği bir Promise<void> döndüren bir fonksiyon yazın, sonra onu bir async fonksiyonun içinde await edin:

await sleep(300) yalnızca main fonksiyonunu duraklatır. Program donmaz: o beklerken timer'lar, diğer async fonksiyonlar ve I/O çalışmaya devam eder.

sleep Fonksiyonu Nasıl Çalışır

setTimeout(resolve, ms), resolve fonksiyonunun ms milisaniye sonra çağrılmasını planlar ve resolve çağrısı promise'i sonuçlandırır. O promise üzerindeki await, async fonksiyonu o ana kadar askıya alır.

<void> tip argümanı önemlidir. Tek başına bir new Promise(...) tipini resolve çağrılarından çıkarmaz, bu yüzden bu argüman olmadan sleep, Promise<unknown> döndürürdü. void ise resolve fonksiyonunun değersiz çağrılmasına izin veren şeydir: bir Promise<number> içinde argümansız resolve() bir derleme hatasıdır. Fonksiyonun belirtilmiş bir dönüş tipi varsa tip argümanı oraya yazılabilir:

setTimeout kesin bir süre değil, bir alt sınır garanti eder: callback, gecikme geçtiğinde ve event loop boş olduğunda çalışır. Birkaç milisaniyelik sapma bekleyin.

Döngü İçinde Beklemek

Bir for ya da for...of döngüsünün içindeki await sleep(), iterasyonlar arasında duraklar; işin hızını böyle ayarlarsınız (rate limit'ler, polling, terminaldeki animasyonlar):

Bu forEach içinde çalışmaz: forEach her async callback'in döndürdüğü promise'i yok sayar, bu yüzden bütün iterasyonlar aynı anda başlar ve hiçbir şey beklemez. async/await sayfasında anlatıldığı gibi bir for ya da for...of döngüsü kullanın.

Gecikmeyle Yeniden Deneme

Yaygın bir gerçek kullanım: bir işlemi deneyin, başarısız olursa bekleyip yeniden deneyin ve her seferinde bekleme süresini ikiye katlayın (exponential backoff).

try içindeki return await fn() önemlidir: await olmadan, reject olan bir promise catch onu göremeden döndürülürdü.

İptal Edilebilir sleep

Düz bir sleep kesilemez. Beklemeyi erken bitirmek için (kullanıcı İptal'e bastı, kapanış başladı) bir AbortSignal verin ve sinyal geldiğinde timer'ı temizleyin:

Uzun timer temizlendiği için program abort'tan hemen sonra sonlanır. clearTimeout olmasaydı Node, 5 saniye dolana kadar çalışmaya devam ederdi.

Node'un Yerleşik Promise Timer'ları

Node, node:timers/promises modülünde setTimeout'un promise sürümünü sunar; bu yüzden Node kodunda yardımcı fonksiyonu yazmak yerine onu import edebilirsiniz. Resolve olacağı bir değeri ve bir AbortSignal'ı da kabul eder:

import { setTimeout as sleep } from "node:timers/promises";

async function main() {
    await sleep(1000);                              // wait one second
    const result = await sleep(500, "done");        // resolves with "done"
    const ac = new AbortController();
    await sleep(10_000, undefined, { signal: ac.signal }); // cancellable
}

Tipler @types/node paketinden gelir (npm i -D @types/node). Bu modül tarayıcılarda yoktur; orada taşınabilir seçim tek satırlık yardımcı fonksiyondur.

Bloklayan sleep Yoktur

Thread'leri olan dillerde mevcut thread'i bloklayan bir sleep bulunur. JavaScript ise kodunuzu bir event loop ile tek bir thread üzerinde çalıştırır, bu yüzden bloklayan bir sleep geri kalan her şeyi dondururdu: hiçbir timer tetiklenmez, hiçbir ağ yanıtı işlenmez ve tarayıcıda sayfa yanıt vermez olur. Saat belirli bir zamanı geçene kadar dönen meşgul bir döngü tam olarak bunu yapar ve asla doğru araç değildir.

JavaScript ve TypeScript'te bekleme async sleep ile olur: fonksiyon askıya alınır, thread serbest kalır ve timer tetiklendiğinde fonksiyon kaldığı yerden devam eder. Atomics.wait gerçekten bloklayabilir, ancak yalnızca bir SharedArrayBuffer üzerinde ve tarayıcılar bunu ana thread'de yasaklar; gecikme için değil, worker thread'lerini koordine etmek için vardır.

Sıkça Sorulan Sorular

TypeScript'te nasıl sleep yapılır?

const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)); tanımlayın ve bir async fonksiyonun içinde await sleep(1000) çağırın. Bu, programın geri kalanını bloklamadan o fonksiyonu yaklaşık bir saniye duraklatır.

TypeScript'te yerleşik bir sleep fonksiyonu var mı?

Hayır. TypeScript JavaScript'e tip ekler ve kendine ait bir çalışma zamanı kütüphanesi yoktur; JavaScript'te de sleep yoktur. Node'da bir tane import edebilirsiniz: import { setTimeout as sleep } from "node:timers/promises". Tarayıcıda tek satırlık yardımcı fonksiyonu yazın.

sleep neden await gerektirir?

sleep(1000) hemen bir promise döndürür; çevreleyen async fonksiyonu promise resolve olana kadar yalnızca await duraklatır. await olmadan sonraki satır hemen çalışır. await yalnızca bir async fonksiyonun içinde (ya da bir ES modülünün en üst seviyesinde) çalışır.

TypeScript'te senkron bir sleep ile thread'i bloklayabilir miyim?

Normal kodda hayır. JavaScript bir event loop ile tek bir thread üzerinde çalışır ve meşgul bekleyen bir döngü her şeyi dondurur: timer'lar, ağ callback'leri, bütün sayfa. Bunun yerine async sleep kullanın. Atomics.wait, Node'da ya da bir worker'da bir thread'i bloklayabilir, ancak bu gecikme için değil, düşük seviyeli worker koordinasyonu içindir.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA