Future/Promise je vzor asynchronního programování představující kontejner pro výsledek dosud nedokončené operace. Podle Dart Documentation, 2025 je Future read-only výsledek odložených výpočtů, Promise je write-only kontrakt, který tento výsledek vyplňuje. Future se používá v Dart, Java, Scala a C++ pro řetězce then/catch.
Hlavní body
Future/Promise je dvojice propojených objektů, které rozdělují asynchronní výsledek do dvou rolí. Promise může zapsat výsledek (resolve) nebo chybu (reject). Future ho může pouze číst — přes callback (then, catchError) nebo přes await. Toto rozdělení zaručuje, že spotřebitel nemůže výsledek změnit, pouze ho použít.
Jazyk Dart používá Future jako hlavní mechanismus asynchronicity. Future<T> je kontrakt na získání hodnoty typu T v budoucnosti. Future může být v jednom ze tří stavů: unresolved (operace se provádí), resolved with value (úspěšně dokončena) nebo resolved with error (dokončena s chybou). Po přechodu do stavu resolved se Future nemění.
Promise v JavaScriptu je obdoba Dartového Future, ale s bohatším API. Promise přijímá executor — funkci s parametry resolve a reject. Statické metody Promise.all, Promise.race, Promise.allSettled umožňují kombinovat několik promiseů. Moderní aplikace používají syntaxi async/await nad Promise.
Future funguje na základě event loop — smyčky událostí, která zpracovává asynchronní operace bez blokování hlavního vlákna. Když je volána asynchronní funkce (např. http.get), okamžitě vrací Future. Skutečný požadavek se provádí na pozadí, zatímco event loop pokračuje ve zpracování dalších událostí. Po dokončení operace Future přejde do stavu resolved a je volán then.
Event loop je klíčový mechanismus, na kterém jsou postaveny Dart a JavaScript. Event loop udržuje dvě fronty: microtask queue (krátké úkoly prováděné před další událostí) a event queue (události IO, časovače). Future.then umístí callback do microtask queue, Future.microtask — prioritní provedení před dalším snímkem.
Řetězce then() umožňují sekvenční zpracování výsledků asynchronních operací bez callback hell. Každý then() obdrží výsledek předchozího kroku a vrátí nový Future. catchError() na konci řetězce zpracovává jakoukoli chybu, která se vyskytla v kterémkoli kroku. To činí asynchronní kód lineárním a čitelným.
V Javě CompletableFuture rozšiřuje koncept Future/Promise. Metoda supplyAsync() spouští asynchronní úlohu ve ForkJoinPool.commonPool(). thenApply() transformuje výsledek, thenCompose() — rozbaluje vnořený CompletableFuture. exceptionally() zpracovává chybu s vrácením výchozí hodnoty. allOf() a anyOf() fungují jako Promise.all a Promise.race v JavaScriptu. CompletableFuture podporuje ruční dokončení pomocí complete() a completeExceptionally() — to je obdoba Promise resolve/reject.
Promise je kontrakt s jedním ze tří stavů: pending (čeká), fulfilled (úspěšně dokončen) nebo rejected (dokončen s chybou). Po přechodu do stavu fulfilled nebo rejected se Promise nikdy nemění — to zaručuje neměnnost výsledku pro všechny spotřebitele. Metoda .then() je volána asynchronně po přechodu do libovolného dokončeného stavu.
Promise.all čeká na dokončení všech předaných promiseů a vrací pole výsledků ve stejném pořadí. Pokud jeden promise skončil chybou — celý Promise.all přechází do rejected. Promise.race vrací výsledek prvního dokončeného promise (úspěch nebo chybu). Promise.allSettled čeká na všechny promisy bez ohledu na chyby — vrací stav každého.
Chaining — klíčová výhoda Promise oproti callback. Každý .then() vrací nový Promise, což umožňuje vytvářet řetězce libovolné délky. Chyba v kterémkoli článku řetězce je propagována k nejbližšímu .catch(). Metoda finally() provádí kód po dokončení řetězce bez ohledu na výsledek — pro čištění zdrojů.
První příklad — vytvoření Future přes async-funkci a zpracování přes then/catchError:
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 1))
return "Data načtena"
}
fetchData()
.then((result) => print(result))
.catchError((error) => print("Chyba: $error"))
Druhý příklad — kombinace několika Future přes Future.wait:
Future<List<String>> loadAll() async {
final futures = [
fetchFromApi("/users"),
fetchFromApi("/posts"),
fetchFromApi("/comments")
]
final results = await Future.wait(futures)
return results
}
Třetí příklad — Promise v JavaScriptu s ručním vytvořením a řetězcem then:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hotovo")
}, 1000)
})
promise
.then(value => console.log(value))
.catch(err => console.error(err))
Future/Promise se liší od stylu callback tím, že vrací objekt-kontrakt namísto přijímání callback funkce jako argumentu. Styl callback vede k vnořování (callback hell), zatímco Future umožňuje vytvářet ploché řetězce then(). Syntaxe async/await činí kód s Future ještě lineárnějším, podobným synchronnímu kódu.
Future představuje přesně jeden asynchronní výsledek — jednu emisi, po které Future končí. Na rozdíl od Observable (Rx, ReactiveX) nebo Flow (Kotlin Coroutines) Future nepodporuje vícenásobné hodnoty v čase. Pokud potřebujete proud událostí — použijte Stream v Dartu, Observable v Rx nebo Flow v Kotlinu.
CompletableFuture v Javě — obdoba Promise s rozšířeným API: supplyAsync, thenApply, thenCompose, exceptionally. CompletableFuture umožňuje kombinovat několik asynchronních operací přes allOf, anyOf, a také nastavit vlastní Executor pro provedení. Scala Future používá ExecutionContext pro správu fondu vláken a podporuje kompozici přes for-comprehension.
V Dartu se vzor Future liší od JavaScript Promise tím, že Dart má přísné typování: Future<String> zaručuje typ vrácené hodnoty. Funkce async v Dartu musí vracet Future a kompilátor kontroluje, zda všechny cesty vracejí správný typ. Future.wait je ekvivalentem Promise.all — přijímá Iterable<Future<T>> a vrací Future<List<T>>. Future.delayed a Future.error jsou pohodlné továrny pro testování asynchronních scénářů.
Future/Promise je implementován v Pythonu přes concurrent.futures.Future a asyncio.Future. concurrent.futures.ThreadPoolExecutor.submit() vrací Future, na kterém lze volat result() — blokující volání. asyncio.Future je await-kompatibilní kontejner pro asynchronní výsledek v Asyncio. asyncio.gather() paralelně spouští několik korutin a vrací seznam výsledků, podobně jako Promise.all v JavaScriptu. Python také používá callback-based asyncio.ensure_future a řetězce add_done_callback pro kompozici asynchronních operací, ale v moderním kódu je preferována syntaxe async/await s asyncio.Task.
V mobilním vývoji je Future aktivně používán ve Flutter aplikacích. Každý síťový požadavek z balíčku http nebo dio vrací Future. FutureBuilder — widget, který přijímá Future a snapshot stavu: connectionDone, hasData, hasError. Při obdržení dat snapshot.data obsahuje výsledek Future. StreamBuilder — obdoba pro vícenásobné hodnoty. FutureBuilder eliminuje ruční správu stavu načítání přes setState.
Scala Future implicitně používá ExecutionContext — fond vláken, na kterém se asynchronní úloha provádí. Kompozice přes map, flatMap, filter funguje díky tomu, že Future je monáda. for-comprehension umožňuje sekvenčně kombinovat několik Future bez vnořování: for { a <- futureA; b <- futureB } yield a + b. Future.sequence funguje jako Promise.all. Fallback při chybě je realizován přes recover a recoverWith.
Future/Promise v C++ je reprezentován třídami std::future a std::promise z knihovny <future>. std::async spouští asynchronní funkci a vrací std::future. std::promise umožňuje ručně nastavit hodnotu přes set_value() nebo chybu přes set_exception(). Na rozdíl od Dartu a JavaScriptu std::future.get() blokuje vlákno, dokud není obdržen výsledek — to je důležitý rozdíl, který je třeba zohlednit při navrhování vícevláknových aplikací v C++.
Při navrhování API vracejících Future dodržujte pravidlo jediného zdroje pravdy: každý asynchronní požadavek je vytvořen jednou a uložen do mezipaměti přes Future.memoize. Pokud dvě komponenty požadují stejná data, obdrží stejný Future — to zabraňuje duplicitě požadavků. Pro timeout použijte Future.timeout (Dart) nebo Promise.race s timeoutem, abyste zaručili, že se asynchronní operace dokončí v rámci zadaného intervalu.
Vzor Retry ve Future je implementován přes rekurzivní řetězec: při chybě v catch je volána stejná asynchronní funkce se zpožděním. Exponential backoff zvyšuje interval mezi pokusy: 1 s — 2 s — 4 s — až max 30 s. V Dartu je to zapouzdřeno v extension na Future: future.retry(maxRetries: 3, delay: Duration(seconds: 1)). Ve Scale Future.zip spojuje dva nezávislé výsledky do tuple — alternativa k Promise.all pro dva Future. Zrušení (Cancellation) není v standardních Future podporováno, ale je implementováno přes CancellationToken nebo AbortController v JavaScriptu.
Často kladené otázky
Future je read-only kontejner pro čtení asynchronního výsledku přes then nebo await. Promise je write-only kontrakt, který přijímá hodnotu přes resolve() a spojuje ji s Future. V Dartu a JavaScriptu jsou tyto pojmy sjednoceny: Future/Promise je jedna třída. V Javě a Scale jsou odděleny.
Future představuje jediný asynchronní výsledek — emituje přesně jednu hodnotu a končí. Observable (Rx) emituje vícenásobné hodnoty v čase — to je asynchronní proud. Pokud potřebujete jednu HTTP odpověď — použijte Future. Pokud potřebujete proud změn databáze — použijte Observable nebo Stream.
async/await je syntaktický cukr nad Future/Promise. Klíčové slovo async označuje funkci jako asynchronní — vrací Future. await pozastaví provádění do dokončení Future, aniž by blokoval vlákno. V Dartu, JavaScriptu, Pythonu a C# async/await nahradil řetězce then ve většině scénářů.
V Dartu použijte .catchError() na konci řetězce — zachycuje výjimky v jakékoli fázi. V JavaScriptu — .catch(). V Dartu je také dostupný try/await/catch uvnitř async funkcí. Pro obnovu po chybě použijte .catchError() s vrácením výchozí hodnoty nebo nového Future.
Promise.all přijímá pole promiseů a vrací jeden Promise, který se vyřeší polem výsledků. Všechny promisy jsou spuštěny paralelně — to urychluje provádění nezávislých operací (např. načítání více souborů). Pokud je kterýkoli promise odmítnut — celý Promise.all je odmítnut se stejnou chybou.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také