
Sleep v JavaScriptu
Jak implementovat sleep/delay funkcionalitu v JavaScriptu pomocí Promise
a async
/await
JavaScript nemá nativní sleep()
funkci jako jiné programovací jazyky. Můžeme ji ale snadno implementovat pomocí Promise
a setTimeout()
.
Základní implementace
const sleep = ms => {
return new Promise(resolve => setTimeout(resolve, ms))
}
const funkce = async () => {
// kód před čekáním
await sleep(5000)
// nějaký kód, co se spustí po 5000 ms
}
Alternativní implementace
Sleep s reject možností
const sleep = (ms, shouldReject = false) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldReject) {
reject(new Error('Sleep interrupted'))
} else {
resolve()
}
}, ms)
})
}
Užitečné pro simulaci chybových stavů nebo testování error handlingu:
const testErrorHandling = async () => {
try {
await sleep(2000, true) // simuluje chybu po 2 sekundách
console.log('Toto se nevypíše')
} catch (error) {
console.log('Zachycena chyba:', error.message)
}
}
// Použití pro testování timeoutů
const simulateTimeout = async () => {
const timeoutPromise = sleep(5000, true)
const dataPromise = fetch('/api/data')
try {
const result = await Promise.race([dataPromise, timeoutPromise])
return result
} catch (error) {
console.log('Timeout nebo chyba:', error.message)
}
}
Sleep s možností zrušení
const sleepWithAbort = (ms) => {
let timeoutId
const promise = new Promise(resolve => {
timeoutId = setTimeout(resolve, ms)
})
promise.abort = () => {
clearTimeout(timeoutId)
}
return promise
}
// Použití
const sleepPromise = sleepWithAbort(5000)
setTimeout(() => sleepPromise.abort(), 2000) // zruší sleep po 2s
Praktické příklady
Simulace API volání
const simulateApiCall = async (data) => {
await sleep(1000 + Math.random() * 2000) // náhodné zpoždění 1-3s
return { success: true, data }
}
Sekvenční zpracování
const processItems = async (items) => {
for (const item of items) {
console.log(`Zpracovávám: ${item}`)
await sleep(1000) // pauza mezi položkami
}
}
Často se hodí v případě opakovaného volání cizích API, aby nedošlo k zahlcení a chybě 429 Too Many Requests.
Při lokalizaci jedné aplikace po jednotlivých částech přes OpenAI API používám sleep pro přidávání prodlevy mezi requesty, když dojde k chybě 429. Tím se vyhnu zahlcení API a zajistím plynulé zpracování celé aplikace.
Dynamický sleep
S hodnotou prodlevy si jde pohrát tak, aby se dynamicky měnila podle odpovědi ze serveru, tj. se prodlužovala při neúspěchu.
const translateWithDynamicRetry = async (text, targetLanguage) => {
let retryCount = 0
let baseDelay = 1000
while (retryCount < 5) {
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [{
role: 'user',
content: `Přelož tento text do ${targetLanguage}: ${text}`
}]
})
})
if (response.status === 429) {
const delay = baseDelay * Math.pow(2, retryCount)
console.log(`Rate limit dosažen, čekám ${delay}ms (pokus ${retryCount + 1})`)
await sleep(delay)
retryCount++
continue
}
return await response.json()
} catch (error) {
console.error('Chyba při překladu:', error)
retryCount++
await sleep(baseDelay * Math.pow(2, retryCount))
}
}
throw new Error('Překročen maximální počet pokusů')
}
Některé API vrací Retry-After
hlavičku s doporučeným časem čekání. Pokud je k disposici, může se použít.
Pozor na blokování
Sleep funkce neblokuje hlavní vlákno:
const demo = async () => {
console.log('Start')
await sleep(3000)
console.log('Konec')
}
demo()
console.log('Toto se vypíše okamžitě')
Výstup:
Start
Toto se vypíše okamžitě
Konec (po 3 sekundách)
Kdy sleep nepoužívat
Řešení časté chyby: místo čekání na čas je lepší počkat na skutečný stav.
Zvlášť začínající programátory může svádět řešit problémy tak, že si někam přidají sleep
jako rychlou opravu chyby.
const checkStatus = async () => {
await sleep(2000) // předpokládáme, že bude hotovo
return getStatus()
}
Lepší je počkat na skutečný výsledek:
const checkStatus = async () => {
const response = await fetch('/api/status')
return response.json()
}
Nebo použít callbacky místo sleep.
Závěr
Sleep funkce je užitečná pro:
- Simulaci API volání
- Rate limiting
- Sekvenční zpracování dat
- Debugging a testování
Doporučuji používat async
/await
zápis pro čitelnější kód a lepší zpracování chyb.
Související články

JavaScript Battery API
Jak v JS zjistit stav baterie, co dnes funguje a kdy API nepoužívat.