Future/Promise — шта је то, асинхрона израчунавања и програмирање

Аутор: IT Sectr Објављено: 2026-03-17 Време читања: 9 мин

Future/Promise је образац асинхроног програмирања који представља контејнер за резултат још незавршене операције. Према Dart Documentation, 2025, Future је read-only резултат одложених израчунавања, Promise је write-only уговор који попуњава овај резултат. Future се користи у Dart, Java, Scala и C++ за ланце then/catch.

Главно

  • Future — read-only контејнер за асинхрони резултат доступан у будућности
  • Promise — write-only пунилац који прихвата резултат и прослеђује га Future-у
  • Ланци then — секвенцијална обрада асинхроних операција без угнежђених callback-а
  • Future у Dart-у — основа async/await и библиотека dio, http, shelf
  • Future/Promise — алтернатива обрасцу callback и основа за async/await синтаксу

Шта је Future/Promise?

Future/Promise је пар повезаних објеката који деле асинхрони резултат на две улоге. Promise може да запише резултат (resolve) или грешку (reject). Future може само да га чита — преко callback-а (then, catchError) или преко await-а. Таква подела гарантује да потрошач не може да промени резултат, већ само да га користи.

Future у Dart-у

Језик Dart користи Future као главни механизам асинхроности. Future<T> је уговор за добијање вредности типа T у будућности. Future може бити у једном од три стања: unresolved (операција се извршава), resolved with value (успешно завршена) или resolved with error (завршена са грешком). Након преласка у resolved стање, Future се не мења.

Promise у JavaScript-у

Promise у JavaScript-у је аналог Dart-овог Future-а, али са богатијим API-јем. Promise прима егзекутор — функцију са параметрима resolve и reject. Статички методи Promise.all, Promise.race, Promise.allSettled омогућавају комбиновање више промиса. Савремене апликације користе async/await синтаксу изнад Promise-а.

Како ради Future

Future ради на основу event loop-а — петље догађаја која обрађује асинхроне операције без блокирања главне нити. Када се позове асинхрона функција (нпр. http.get), она одмах враћа Future. Стварни захтев се извршава у позадини, а event loop наставља да обрађује друге догађаје. Након завршетка операције, Future прелази у resolved стање и позива се then.

Event loop је кључни механизам на коме су изграђени Dart и JavaScript. Event loop одржава два реда: microtask queue (кратки задаци који се извршавају пре следећег догађаја) и event queue (IO догађаји, тајмери). Future.then смешта callback у microtask queue, Future.microtask — приоритетно извршавање пре следећег кадра.

Ланци then() омогућавају секвенцијалну обраду резултата асинхроних операција без callback hell-а. Сваки then() добија резултат претходног корака и враћа нови Future. catchError() на крају ланца обрађује било коју грешку која се појавила у било ком кораку. Ово чини асинхрони код линеарним и читљивим.

CompletableFuture у Java-и

У Java-и CompletableFuture проширује концепт Future/Promise. Метод supplyAsync() покреће асинхрони задатак у ForkJoinPool.commonPool(). thenApply() трансформише резултат, thenCompose() — развија угнежђени CompletableFuture. exceptionally() обрађује грешку са враћањем подразумеване вредности. allOf() и anyOf() раде као Promise.all и Promise.race у JavaScript-у. CompletableFuture подржава ручно завршавање кроз complete() и completeExceptionally() — ово је аналог Promise resolve/reject.

Promise и уговор асинхроности

Promise је уговор са једним од три стања: pending (чекање), fulfilled (успешно завршен) или rejected (завршен са грешком). Након преласка у fulfilled или rejected стање, Promise се никада не мења — ово гарантује имутабилност резултата за све потрошаче. Метод .then() се позива асинхроно након преласка у било које завршно стање.

Promise.all чека завршетак свих прослеђених промиса и враћа низ резултата у истом редоследу. Ако се један промис завршио грешком — цео Promise.all прелази у rejected. Promise.race враћа резултат првог завршеног промиса (успех или грешка). Promise.allSettled чека све промисe без обзира на грешке — враћа статус сваког.

Chaining — кључна предност Promise-а у односу на callback. Сваки .then() враћа нови Promise, омогућавајући изградњу ланаца произвољне дужине. Грешка у било којој карици ланца се преноси до најближег .catch(). Метод finally() извршава код након завршетка ланца без обзира на резултат — за чишћење ресурса.

Примери кода Future (Dart)

Први пример — креирање Future-а кроз async-функцију и обрада кроз then/catchError:

dart
Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 1))
    return "Подаци су учитани"
}

fetchData()
    .then((result) => print(result))
    .catchError((error) => print("Грешка: $error"))

Други пример — комбиновање више Future-а кроз Future.wait:

dart
Future<List<String>> loadAll() async {
    final futures = [
        fetchFromApi("/users"),
        fetchFromApi("/posts"),
        fetchFromApi("/comments")
    ]
    final results = await Future.wait(futures)
    return results
}

Трећи пример — Promise у JavaScript-у са ручним креирањем и ланцем then:

js
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Готово")
    }, 1000)
})

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

Future vs други асинхрони обрасци

Future/Promise се разликује од callback стила по томе што враћа објекат-уговор уместо да прима функцију повратног позива као аргумент. Callback стил доводи до угнежђивања (callback hell), док Future омогућава изградњу равних ланаца then(). async/await синтакса чини код са Future-ом још линеарнијим, сличним синхроном.

Future представља тачно један асинхрони резултат — једну емисију, након чега се Future завршава. За разлику од Observable (Rx, ReactiveX) или Flow (Kotlin Coroutines), Future не подржава вишеструке вредности током времена. Ако је потребан ток догађаја — користите Stream у Dart-у, Observable у Rx-у или Flow у Kotlin-у.

CompletableFuture у Java-и — аналог Promise-а са проширеним API-јем: supplyAsync, thenApply, thenCompose, exceptionally. CompletableFuture омогућава комбиновање више асинхроних операција кроз allOf, anyOf, као и постављање сопственог Executor-а за извршење. Scala Future користи ExecutionContext за управљање pool-ом нити и подржава композицију кроз for-comprehension.

У Dart-у се образац Future разликује од JavaScript Promise-а по томе што Dart има строгу типизацију: Future<String> гарантује тип повратне вредности. async функције у Dart-у морају да враћају Future, а компајлер проверава да ли све путање враћају исправан тип. Future.wait је еквивалент Promise.all-у — прима Iterable<Future<T>> и враћа Future<List<T>>. Future.delayed и Future.error су згодне фабрике за тестирање асинхроних сценарија.

Future/Promise је имплементиран у Python-у кроз concurrent.futures.Future и asyncio.Future. concurrent.futures.ThreadPoolExecutor.submit() враћа Future на коме се може позвати result() — блокирајући позив. asyncio.Future је await-компатибилан контејнер за асинхрони резултат у Asyncio-у. asyncio.gather() паралелно покреће више корутина и враћа листу резултата, слично Promise.all-у у JavaScript-у. Python такође користи callback-based asyncio.ensure_future и ланце add_done_callback за композицију асинхроних операција, али се у савременом коду предност даје async/await синтакси са asyncio.Task.

У мобилном развоју Future се активно користи у Flutter апликацијама. Сваки мрежни захтев из пакета http или dio враћа Future. FutureBuilder — widget који прима Future и snapshot стања: connectionDone, hasData, hasError. По пријему података, snapshot.data садржи резултат Future-а. StreamBuilder — аналог за вишеструке вредности. FutureBuilder елиминише ручно управљање стањем учитавања кроз setState.

Scala Future имплицитно користи ExecutionContext — pool нити на коме се извршава асинхрони задатак. Композиција кроз map, flatMap, filter функционише захваљујући томе што је Future монада. for-comprehension омогућава секвенцијално комбиновање више Future-а без угнежђивања: for { a <- futureA; b <- futureB } yield a + b. Future.sequence ради као Promise.all. Повратак на резервну вредност при грешци се реализује кроз recover и recoverWith.

Future/Promise у C++-у је представљен класама std::future и std::promise из библиотеке <future>. std::async покреће асинхрону функцију и враћа std::future. std::promise омогућава ручно постављање вредности кроз set_value() или грешке кроз set_exception(). За разлику од Dart-а и JavaScript-а, std::future.get() блокира нит до добијања резултата — ово је важна разлика коју треба узети у обзир при пројектовању вишеструконитних апликација у C++-у.

Обрасци рада са Future-ом

При пројектовању API-ја који враћају Future, придржавајте се правила јединственог извора истине: сваки асинхрони захтев се креира једном и кешира кроз Future.memoize. Ако две компоненте захтевају исте податке, оне добијају исти Future — ово спречава дуплирање захтева. За timeout користите Future.timeout (Dart) или Promise.race са timeout-ом да бисте гарантовали да ће се асинхрона операција завршити у оквиру задатог интервала.

Retry образац у Future-у се реализује кроз рекурзивни ланац: при грешци у catch-у се позива иста асинхрона функција са кашњењем. Exponential backoff повећава интервал између покушаја: 1 сек — 2 сек — 4 сек — до макс 30 сек. У Dart-у се ово инкапсулира у extension на Future: future.retry(maxRetries: 3, delay: Duration(seconds: 1)). У Scala-и Future.zip спаја два независна резултата у tuple — алтернатива Promise.all-у за два Future-а. Отказивање (Cancellation) у стандардним Future-има није подржано, али се реализује кроз CancellationToken или AbortController у JavaScript-у.

Често постављана питања

Која је разлика између Future-а и Promise-а?

Future је read-only контејнер за читање асинхроног резултата кроз then или await. Promise је write-only уговор који прихвата вредност кроз resolve() и повезује је са Future-ом. У Dart-у и JavaScript-у су ови појмови обједињени: Future/Promise је једна класа. У Java-и и Scala-и су раздвојени.

Чим се Future разликује од Observable-а?

Future представља један асинхрони резултат — емитује тачно једну вредност и завршава се. Observable (Rx) емитује вишеструке вредности током времена — то је асинхрони ток. Ако вам је потребан један HTTP одговор — користите Future. Ако вам је потребан ток промена базе података — користите Observable или Stream.

Шта је async/await и како је повезано са Future-ом?

async/await је синтаксни шећер изнад Future/Promise. Кључна реч async означава функцију као асинхрону — она враћа Future. await зауставља извршавање до завршетка Future-а, не блокирајући нит. У Dart-у, JavaScript-у, Python-у и C#-у, async/await је заменио ланце then у већини сценарија.

Како обрађивати грешке у ланцу Future-а?

У Dart-у користите .catchError() на крају ланца — он хвата изузетке у било којој фази. У JavaScript-у — .catch(). У Dart-у је такође доступан try/await/catch унутар async функција. За опоравак након грешке користите .catchError() са враћањем подразумеване вредности или новог Future-а.

Шта је Promise.all и када га користити?

Promise.all прима низ промиса и враћа један Promise који се разрешава низом резултата. Сви промисu се покрећу паралелно — ово убрзава извршавање независних операција (нпр. учитавање више датотека). Ако је било који промис одбијен — цео Promise.all се одбија са истом грешком.

Резиме

  • Future/Promise — образац асинхроног програмирања са уговором за једну вредност
  • Future — read-only контејнер за читање резултата операције
  • Promise — write-only уговор који попуњава Future кроз resolve/reject
  • Ланци then — равна обрада асинхроних корака без callback hell-а
  • async/await — синтаксни шећер изнад Future-а, чини код линеарним
  • Promise.all — паралелно покретање више асинхроних операција
  • За вишеструке вредности током времена користите Stream или Observable, а не Future

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође