Future/Promise este un model de programare asincronă, reprezentând un container pentru rezultatul unei operații încă nefinalizate. Conform Dart Documentation, 2025, Future este rezultatul read-only al calculelor amânate, Promise este contractul write-only care completează acest rezultat. Future este utilizat în Dart, Java, Scala și C++ pentru lanțuri then/catch.
Principalele puncte
Future/Promise este o pereche de obiecte interdependente care împart rezultatul asincron în două roluri. Promise poate scrie rezultatul (resolve) sau eroarea (reject). Future poate doar să îl citească — prin callback (then, catchError) sau prin await. Această separare garantează că consumatorul nu poate modifica rezultatul, ci doar să îl utilizeze.
Limbajul Dart utilizează Future ca mecanism principal de asincronitate. Future<T> este un contract pentru primirea unei valori de tip T în viitor. Future poate fi într-una din trei stări: unresolved (operația se execută), resolved with value (finalizată cu succes) sau resolved with error (finalizată cu eroare). După trecerea în starea resolved, Future nu se mai modifică.
Promise în JavaScript este analogul Future din Dart, dar cu un API mai bogat. Promise primește un executor — o funcție cu parametrii resolve și reject. Metodele statice Promise.all, Promise.race, Promise.allSettled permit combinarea mai multor promise-uri. Aplicațiile moderne utilizează sintaxa async/await bazată pe Promise.
Future funcționează pe baza event loop — bucla de evenimente care procesează operații asincrone fără a bloca firul principal. Când este apelată o funcție asincronă (de exemplu, http.get), ea returnează imediat un Future. Solicitarea reală se execută în fundal, iar event loop continuă să proceseze alte evenimente. După finalizarea operației, Future trece în starea resolved și este apelat then.
Event loop este mecanismul cheie pe care sunt construite Dart și JavaScript. Event loop menține două cozi: microtask queue (sarcini scurte executate înainte de următorul eveniment) și event queue (evenimente IO, timer-e). Future.then plasează callback-ul în microtask queue, Future.microtask — execuție prioritară înainte de următorul cadru.
Lanțurile then() permit procesarea secvențială a rezultatelor operațiilor asincrone fără callback hell. Fiecare then() primește rezultatul pasului anterior și returnează un nou Future. catchError() la sfârșitul lanțului procesează orice eroare apărută la orice etapă. Aceasta face codul asincron liniar și lizibil.
În Java, CompletableFuture extinde conceptul Future/Promise. Metoda supplyAsync() lansează o sarcină asincronă în ForkJoinPool.commonPool(). thenApply() transformă rezultatul, thenCompose() — desface un CompletableFuture imbricat. exceptionally() procesează eroarea cu returnarea unei valori implicite. allOf() și anyOf() funcționează ca Promise.all și Promise.race în JavaScript. CompletableFuture suportă finalizarea manuală prin complete() și completeExceptionally() — acesta este analogul Promise resolve/reject.
Promise este un contract cu una din trei stări: pending (în așteptare), fulfilled (finalizat cu succes) sau rejected (finalizat cu eroare). După trecerea în starea fulfilled sau rejected, Promise nu se mai modifică niciodată — aceasta garantează imutabilitatea rezultatului pentru toți consumatorii. Metoda .then() este apelată asincron după trecerea în orice stare finalizată.
Promise.all așteaptă finalizarea tuturor promise-urilor transmise și returnează un array de rezultate în aceeași ordine. Dacă un promise s-a finalizat cu eroare — întregul Promise.all trece în rejected. Promise.race returnează rezultatul primului promise finalizat (succes sau eroare). Promise.allSettled așteaptă toate promise-urile indiferent de erori — returnează statusul fiecăruia.
Chaining — avantajul cheie al Promise față de callback. Fiecare .then() returnează un nou Promise, permițând construirea de lanțuri de lungime arbitrară. O eroare în orice verigă a lanțului este propagată până la cel mai apropiat .catch(). Metoda finally() execută cod după finalizarea lanțului indiferent de rezultat — pentru curățarea resurselor.
Primul exemplu — crearea unui Future printr-o funcție async și procesarea prin then/catchError:
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 1))
return "Date încărcate"
}
fetchData()
.then((result) => print(result))
.catchError((error) => print("Eroare: $error"))
Al doilea exemplu — combinarea mai multor Future prin Future.wait:
Future<List<String>> loadAll() async {
final futures = [
fetchFromApi("/users"),
fetchFromApi("/posts"),
fetchFromApi("/comments")
]
final results = await Future.wait(futures)
return results
}
Al treilea exemplu — Promise în JavaScript cu creare manuală și lanț then:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Gata")
}, 1000)
})
promise
.then(value => console.log(value))
.catch(err => console.error(err))
Future/Promise se deosebește de stilul callback prin faptul că returnează un obiect-contract în loc să primească o funcție de apel invers ca argument. Stilul callback duce la imbricare (callback hell), pe când Future permite construirea de lanțuri then() plate. Sintaxa async/await face codul cu Future și mai liniar, asemănător celui sincron.
Future reprezintă exact un rezultat asincron — o singură emisie, după care Future se încheie. Spre deosebire de Observable (Rx, ReactiveX) sau Flow (Kotlin Coroutines), Future nu suportă valori multiple în timp. Dacă aveți nevoie de un flux de evenimente — utilizați Stream în Dart, Observable în Rx sau Flow în Kotlin.
CompletableFuture în Java — analogul Promise cu API extins: supplyAsync, thenApply, thenCompose, exceptionally. CompletableFuture permite combinarea mai multor operații asincrone prin allOf, anyOf, precum și setarea unui Executor propriu pentru execuție. Scala Future utilizează ExecutionContext pentru gestionarea pool-ului de fire și suportă compoziția prin for-comprehension.
În Dart, modelul Future diferă de JavaScript Promise prin faptul că Dart are tipizare strictă: Future<String> garantează tipul valorii returnate. Funcțiile async în Dart trebuie să returneze Future, iar compilatorul verifică dacă toate căile returnează tipul corect. Future.wait este echivalentul lui Promise.all — primește Iterable<Future<T>> și returnează Future<List<T>>. Future.delayed și Future.error sunt fabrici convenabile pentru testarea scenariilor asincrone.
Future/Promise este implementat în Python prin concurrent.futures.Future și asyncio.Future. concurrent.futures.ThreadPoolExecutor.submit() returnează un Future pe care se poate apela result() — un apel blocant. asyncio.Future este un container compatibil cu await pentru rezultatul asincron în Asyncio. asyncio.gather() lansează paralel mai multe corutine și returnează o listă de rezultate, similar cu Promise.all în JavaScript. Python utilizează de asemenea asyncio.ensure_future bazat pe callback și lanțuri add_done_callback pentru compoziția operațiilor asincrone, dar în codul modern se preferă sintaxa async/await cu asyncio.Task.
În dezvoltarea mobilă, Future este utilizat activ în aplicațiile Flutter. Fiecare solicitare de rețea din pachetul http sau dio returnează un Future. FutureBuilder — un widget care primește un Future și un snapshot al stării: connectionDone, hasData, hasError. La primirea datelor, snapshot.data conține rezultatul Future. StreamBuilder — analog pentru valori multiple. FutureBuilder elimină gestionarea manuală a stării de încărcare prin setState.
Scala Future utilizează implicit ExecutionContext — pool-ul de fire pe care se execută sarcina asincronă. Compoziția prin map, flatMap, filter funcționează deoarece Future este o monadă. for-comprehension permite combinarea secvențială a mai multor Future fără imbricare: for { a <- futureA; b <- futureB } yield a + b. Future.sequence funcționează ca Promise.all. Fallback-ul la eroare se realizează prin recover și recoverWith.
Future/Promise în C++ este reprezentat de clasele std::future și std::promise din biblioteca <future>. std::async lansează o funcție asincronă și returnează std::future. std::promise permite setarea manuală a valorii prin set_value() sau a erorii prin set_exception(). Spre deosebire de Dart și JavaScript, std::future.get() blochează firul până la primirea rezultatului — aceasta este o diferență importantă care trebuie luată în considerare la proiectarea aplicațiilor multi-fir în C++.
La proiectarea API-urilor care returnează Future, respectați regula sursei unice de adevăr: fiecare solicitare asincronă este creată o singură dată și stocată în cache prin Future.memoize. Dacă două componente solicită aceleași date, ele primesc același Future — aceasta previne duplicarea solicitărilor. Pentru timeout, utilizați Future.timeout (Dart) sau Promise.race cu timeout pentru a garanta că operația asincronă se finalizează în intervalul specificat.
Modelul Retry în Future se implementează printr-un lanț recursiv: la eroare în catch, aceeași funcție asincronă este apelată cu întârziere. Exponential backoff mărește intervalul între încercări: 1 sec — 2 sec — 4 sec — până la max 30 sec. În Dart, aceasta este încapsulată într-un extension pe Future: future.retry(maxRetries: 3, delay: Duration(seconds: 1)). În Scala, Future.zip combină două rezultate independente într-un tuplu — alternativă la Promise.all pentru două Future. Anularea (Cancellation) în Future standard nu este suportată, dar se implementează prin CancellationToken sau AbortController în JavaScript.
Întrebări frecvente
Future este un container read-only pentru citirea rezultatului asincron prin then sau await. Promise este un contract write-only care primește valoarea prin resolve() și o leagă de Future. În Dart și JavaScript, aceste concepte sunt unite: Future/Promise este o singură clasă. În Java și Scala, ele sunt separate.
Future reprezintă un singur rezultat asincron — emite exact o valoare și se încheie. Observable (Rx) emite valori multiple în timp — este un flux asincron. Dacă aveți nevoie de un singur răspuns HTTP — utilizați Future. Dacă aveți nevoie de un flux de modificări ale bazei de date — utilizați Observable sau Stream.
async/await este zahăr sintactic peste Future/Promise. Cuvântul cheie async marchează o funcție ca asincronă — ea returnează un Future. await suspendă execuția până la finalizarea Future, fără a bloca firul. În Dart, JavaScript, Python și C#, async/await a înlocuit lanțurile then în majoritatea scenariilor.
În Dart, utilizați .catchError() la sfârșitul lanțului — acesta prinde excepții în orice etapă. În JavaScript — .catch(). În Dart este disponibil și try/await/catch în interiorul funcțiilor async. Pentru recuperarea după o eroare, utilizați .catchError() cu returnarea unei valori implicite sau a unui nou Future.
Promise.all primește un array de promise-uri și returnează un singur Promise care se rezolvă cu un array de rezultate. Toate promise-urile sunt lansate paralel — aceasta accelerează executarea operațiilor independente (de exemplu, încărcarea mai multor fișiere). Dacă orice promise este respins — întregul Promise.all este respins cu aceeași eroare.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și