Future/Promise — ce este, calcule asincrone și programare

Autor: IT Sectr Publicat: 2026-03-17 Timp de citire: 9 min

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 — container read-only pentru rezultatul asincron disponibil în viitor
  • Promise — umplutor write-only care primește rezultatul și îl transmite către Future
  • Lanțurile then — procesarea secvențială a operațiilor asincrone fără callback-uri imbricate
  • Future în Dart — baza async/await și a bibliotecilor dio, http, shelf
  • Future/Promise — alternativă la modelul callback și baza sintaxei async/await

Ce este Future/Promise?

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.

Future în Dart

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

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.

Cum funcționează Future

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.

CompletableFuture în Java

Î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 și contractul de asincronitate

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.

Exemple de cod Future (Dart)

Primul exemplu — crearea unui Future printr-o funcție async și procesarea prin then/catchError:

dart
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:

dart
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:

js
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Gata")
    }, 1000)
})

promise
    .then(value => console.log(value))
    .catch(err => console.error(err))

Future vs alte modele asincrone

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++.

Modele de lucru cu Future

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

Care este diferența dintre Future și Promise?

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.

Cu ce se deosebește Future de Observable?

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.

Ce este async/await și cum se leagă de Future?

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.

Cum se procesează erorile într-un lanț Future?

Î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.

Ce este Promise.all și când se utilizează?

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

  • Future/Promise — model de programare asincronă cu contract pentru o singură valoare
  • Future — container read-only pentru citirea rezultatului operației
  • Promise — contract write-only care completează Future prin resolve/reject
  • Lanțurile then — procesarea plată a pașilor asincroni fără callback hell
  • async/await — zahăr sintactic peste Future, face codul liniar
  • Promise.all — lansarea paralelă a mai multor operații asincrone
  • Pentru valori multiple în timp, utilizați Stream sau Observable, nu Future

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.

Discutați proiectul

Citiți și