07.04 Promises úvod
Výuka
Co je Promise?
Promise (příslib, slib) je objekt reprezentující budoucí hodnotu - něco, co možná ještě není dostupné, ale bude (nebo nastane chyba).
Představ si to jako:
Jdeš do fastfoodu a objednáš si burger. Zaplatíš 100 Kč. Burger není hned připravený, takže ti dají stvrzenku s číslem objednávky.
🧾 Stvrzenka = Promise
Číslo objednávky: #42
Představuje: budoucí burger
Status: čeká se na přípravu
Co stvrzenka znamená:
- ✅ Budeš mít burger (eventually)
- ⏳ Zatím ho nemáš, ale máš záruku, že přijde
- 📱 Můžeš dělat jiné věci (volat kamarádovi, sednout si) - nečekáš u pultu!
- 🔔 Dostaneš upozornění, až bude hotovo
Dva možné výsledky:
- ✅ Fulfilled (splněno) - dostaneš burger
- ❌ Rejected (odmítnuto) - "Omlouváme se, burgery došly"
Proč Promises?
Callbacks měly 2 velké problémy:
1. Inversion of Control (Ztráta kontroly)
S callbacky předáváš kontrolu někomu jinému:
// Předáváš svůj callback třetí straně
analytics.trackPurchase(data, function myCallback() {
chargeCreditCard(); // Důvěřuješ, že to zavolá JEDNOU!
});
Problém: Nevíš, jestli třetí strana:
- Zavolá callback 1x, 5x, nebo 0x
- Zavolá ho včas
- Předá správné parametry
Promise řešení: Místo předání callbacku dostaneš objekt (Promise), který kontroluješ TY:
// Dostáváš Promise - kontroluješ ho TY!
const promise = analytics.trackPurchase(data);
promise.then(() => {
chargeCreditCard(); // TY rozhoduješ, co se stane
});
2. Callback Hell (Pyramid of Doom)
Vnořené callbacky = nečitelný kód.
Promise řešení: Lineární řetězení:
// ❌ Callback hell
step1((result1) => {
step2(result1, (result2) => {
step3(result2, (result3) => {
done(result3);
});
});
});
// ✅ Promises - lineární!
step1()
.then(result1 => step2(result1))
.then(result2 => step3(result2))
.then(result3 => done(result3));
Jak Promise funguje?
Promise je stavový automat - může být v jednom ze 3 stavů:
┌──────────────┐
│ PENDING │ ← Čeká se (výchozí stav)
│ (čekající) │
└──────┬───────┘
│
↓
┌────┴────┐
│ │
↓ ↓
┌─────────┐ ┌─────────┐
│FULFILLED│ │REJECTED │
│(splněno)│ │(odmítnuté)│
└─────────┘ └─────────┘
Pravidla:
- ⏳ Pending → může přejít na Fulfilled nebo Rejected
- ✅ Fulfilled → FINÁLNÍ stav (už se nemění)
- ❌ Rejected → FINÁLNÍ stav (už se nemění)
- 🔒 Immutable - jakmile je promise vyřešena, nemůže se změnit
Metafora s burgerem:
- Pending: Burger se vaří
- Fulfilled: Máš burger v ruce ✅
- Rejected: "Burgery došly" ❌
- Immutable: Už to nemůžeš změnit - buď máš burger, nebo ne
Klíčové koncepty
- Future Value (budoucí hodnota) - Promise reprezentuje hodnotu, která přijde později
- Time-independent (nezávislý na čase) - Promise funguje stejně, ať hodnota přijde hned nebo za hodinu
- Immutable (neměnný) - Vyřešený promise se už nemění
- Chainable (řetězitelný) - Můžeš řetězit
.then()za sebou
JavaScript
Vytvoření Promise
// Promise.resolve - vytvoř okamžitě vyřešený promise
const promise = Promise.resolve(42);
promise.then((value) => {
console.log(value); // 42
});
// Promise constructor - pro async operace
const asyncPromise = new Promise((resolve, reject) => {
// Simulace async operace
setTimeout(() => {
resolve('Hotovo po 1 sekundě');
}, 1000);
});
asyncPromise.then((result) => {
console.log(result); // "Hotovo po 1 sekundě" (po 1s)
});
Co se stalo?
Promise.resolve(42)vytvoří okamžitě vyřešený promise s hodnotou 42.then()zaregistruje callback, který se zavolá s hodnotou- Promise constructor dostane funkci
(resolve, reject) => {} - Když zavoláš
resolve(value), promise přejde do stavu Fulfilled
Promise constructor - podrobně
new Promise((resolve, reject) => {
// Tady je tvůj async kód
// Úspěch → zavolej resolve
if (/* vše OK */) {
resolve(value); // Promise → Fulfilled s hodnotou
}
// Chyba → zavolej reject
if (/* chyba */) {
reject(error); // Promise → Rejected s chybou
}
});
Praktický příklad - obalení callback API do Promise
// Callback-based API (Node.js)
function readFileCallback(filename, callback) {
setTimeout(() => {
if (filename.endsWith('.txt')) {
callback(null, 'Obsah souboru');
} else {
callback(new Error('Neplatný soubor'));
}
}, 1000);
}
// Promise wrapper
function readFilePromise(filename) {
return new Promise((resolve, reject) => {
readFileCallback(filename, (err, data) => {
if (err) {
reject(err); // Chyba → rejected
} else {
resolve(data); // Úspěch → fulfilled
}
});
});
}
// Použití
readFilePromise('data.txt').then((data) => {
console.log('Data:', data);
});
// Výstup (po 1s):
// Data: Obsah souboru
Future Value - příklad s cheeseburgerem
// Funkce vrací Promise (stvrzenku)
function orderCheeseburger() {
return new Promise((resolve, reject) => {
console.log('Připravuji burger...');
setTimeout(() => {
const burgersAvailable = true;
if (burgersAvailable) {
resolve('🍔 Váš burger'); // Fulfilled
} else {
reject('❌ Burgery došly'); // Rejected
}
}, 2000);
});
}
// Dostaneš Promise (stvrzenku)
const receipt = orderCheeseburger();
console.log('Mám stvrzenku, zatím dělám jiné věci...');
// Až bude hotovo, dostaneš upozornění
receipt.then((burger) => {
console.log('Mám burger!', burger);
});
// Výstup:
// Připravuji burger...
// Mám stvrzenku, zatím dělám jiné věci...
// (po 2s): Mám burger! 🍔 Váš burger
Co se stalo?
orderCheeseburger()vrátí Promise (stvrzenku) - OKAMŽITĚ- Program pokračuje dál (neblokuje se)
- Po 2 sekundách se Promise vyřeší → zavolá se
.then()callback
Promise je immutable
const promise = Promise.resolve(42);
promise.then(value => console.log('První:', value));
promise.then(value => console.log('Druhý:', value));
promise.then(value => console.log('Třetí:', value));
// Výstup:
// První: 42
// Druhý: 42
// Třetí: 42
// Promise se NEVYČERPÁ! Můžeš ho použít vícekrát.
TypeScript
TypeScript přidává generické typy pro Promise: Promise
Typované Promises
// Promise<number> - promise s číselnou hodnotou
const numberPromise: Promise<number> = Promise.resolve(42);
numberPromise.then((value: number) => {
console.log(value.toFixed(2)); // ✅ TS ví, že je to number
});
// Promise<string>
const stringPromise: Promise<string> = Promise.resolve('Hello');
stringPromise.then((value: string) => {
console.log(value.toUpperCase()); // ✅ TS ví, že je to string
});
// Promise<User>
interface User {
id: number;
name: string;
}
const userPromise: Promise<User> = new Promise((resolve) => {
setTimeout(() => {
resolve({ id: 1, name: 'Jan' });
}, 1000);
});
userPromise.then((user: User) => {
console.log(user.name); // ✅ TS ví, že user má property name
});
Funkce vracející Promise
// Explicitní návratový typ: Promise<string>
function fetchData(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Data loaded');
}, 1000);
});
}
// TS automaticky odvodí Promise<number>
function calculate() {
return Promise.resolve(42); // Promise<number> (inference)
}
Promise constructor s typy
// Typy pro resolve a reject
const promise = new Promise<string>((resolve, reject) => {
// resolve očekává string
resolve('OK'); // ✅
// resolve('OK'); - kdyby se to zakomentovalo
// reject(new Error('Chyba')); // ✅
// resolve(123); // ❌ Error - očekává string
});
Rozdíl JS vs TS
JavaScript:
- Promise bez typů
- Nevíš, co dostaneš v
.then() - Chyby až za běhu
TypeScript:
Promise- víš přesně, jaký typ dostaneš- Autocomplete v
.then()callbacku - Kontrola typů při compilaci
// JS - nevíš co dostaneš
fetchData().then((data) => {
console.log(data.toUpperCase()); // Možná chyba (pokud není string)
});
// TS - víš přesně
fetchData().then((data: string) => {
console.log(data.toUpperCase()); // ✅ TS ví, že je to string
// console.log(data.toFixed()); // ❌ Error - string nemá toFixed
});
Tip
💡 Promise states diagram:
┌─────────────┐
│ PENDING │ (výchozí stav)
└──────┬──────┘
│
┌─────┴─────┐
│ │
↓ ↓
FULFILLED REJECTED
(success) (error)
💡 Promise je jako účtenka:
// Dostaneš účtenku (Promise) OKAMŽITĚ
const receipt = orderFood();
// Můžeš dělat jiné věci
goToTable();
callFriend();
// Až jídlo dorazí, dostaneš upozornění
receipt.then(food => eat(food));
💡 Promises vs Callbacks - Future Value:
// ❌ Callback - "zavolej mě, až máš hodnotu"
fetchData((err, data) => {
if (err) { /* ... */ }
console.log(data);
});
// ✅ Promise - "dej mi účtenku, já počkám"
const promise = fetchData();
promise.then(data => console.log(data));
💡 Promise.resolve - zkratka:
// Dlouhá cesta
const promise = new Promise((resolve) => {
resolve(42);
});
// Zkratka
const promise = Promise.resolve(42);
💡 Immutability = bezpečnost:
const promise = fetchData();
// Můžeš předat komukoliv - nikdo ho nemůže změnit!
module1.use(promise);
module2.use(promise);
// Oba dostanou stejnou hodnotu, nikdo ji nezmění
Kvíz
Které výroky o Promises jsou pravdivé?
✅ - Promise je "účtenka" za budoucí hodnotu - může být dostupná hned nebo později
✅ - 3 stavy: Pending (čeká), Fulfilled (úspěch), Rejected (chyba)
❌ - Promise je immutable - jakmile je vyřešen, NIKDY se už nezmění!
✅ - S callbacky ztrácíš kontrolu, Promise ti dává objekt, který kontroluješ TY
🎯 Závěrečný projekt
Po dokončení všech 8 dílů vytvoříte jednoduchou Todо aplikaci v čistém JavaScriptu. Naučíte se, jak aplikovat vše, co jste se naučili, na reálný projekt.
Zobrazit podrobnosti projektu →Informace o seriálu
Obtížnost
Délka
Cca 480 minut
Počet videí
8 videí + projekty
Certifikát
Po dokončení obdržíte certifikát
Lekce v této sekci
- 7.1 Synchronní vs asynchronní programování
- 7.2 Callbacks
- 07.03 Callback Hell
- 07.04 Promises úvod
- 07.05 Then a Catch
- 07.06 Promise.all
- 07.07 Promise.race
- 07.08 Async/Await
- 07.09 Try/Catch s async
- 07.10 Fetch API
- 7.11 Generátory
Struktura lekcí (souborový strom)
- 1.1 Úvod do JavaScriptu a TypeScriptu
- 1.2 Nastavení prostředí
- 1.3 První program
- 1.4 Proměnné: var, let, const
- 1.5 Datové typy - přehled
- 1.6 String (řetězce)
- 1.7 Number (čísla)
- 1.8 Boolean (pravda/nepravda)
- 1.9 Null a Undefined
- 1.10 Type Inference vs Annotations
- 1.11 Aritmetické operátory
- 1.12 Porovnávací operátory
- 1.13 Logické operátory
- 1.14 Komentáře
- 1.15 Console metody
- 03.01 Deklarace funkce
- 03.02 Function Expression
- 03.03 Arrow Functions
- 03.04 Parametry a argumenty
- 03.05 Return hodnoty
- 03.06 Výchozí parametry
- 03.07 Rest parametry
- 03.08 Co je Scope
- 03.09 Lexikální Scope
- 03.10 Řetězec Scope
- 03.11 Globální Scope
- 03.12 Životní Cyklus Proměnných
- 03.13 Omezení Scope
- 03.14 Použití Closures
- 03.15 Callback funkce
- 03.16 Higher-order Functions
- 03.17 IIFE
- 03.18 Void funkce
- 03.19 Rekurze
- v přípravě
- v přípravě
- v přípravě
- v přípravě
- 01 — Co je Next.js
- 02 — Vytvoření projektu
- 03 — Struktura projektu (app/)
- 04 — Page komponenty (page.js / page.tsx)
- 05 — Layout komponenty (layout.js / layout.tsx)
- 06 — File-based routing
- 07 — Dynamické routy ([id]/page.js)
- 08 — Link komponenta (navigace)
- 09 — Image komponenta (next/image)
- 10 — Metadata (title, description, Open Graph)
- 11 — Loading UI (loading.js / loading.tsx)
- 12 — Error handling (error.js / error.tsx)
- 13 — Not Found (not-found.js / not-found.tsx)
- v přípravě
- v přípravě
- v přípravě