Future/Promise är ett mönster för asynkron programmering som representerar en behållare för resultatet av en ännu inte slutförd operation. Enligt Dart Documentation, 2025 är Future ett read-only resultat av uppskjutna beräkningar, Promise är ett write-only kontrakt som fyller detta resultat. Future används i Dart, Java, Scala och C++ för then/catch-kedjor.
Huvudpunkter
Future/Promise är ett par sammankopplade objekt som delar upp det asynkrona resultatet i två roller. Promise kan skriva resultatet (resolve) eller felet (reject). Future kan bara läsa det — via callback (then, catchError) eller via await. Denna uppdelning garanterar att konsumenten inte kan ändra resultatet, bara använda det.
Språket Dart använder Future som den främsta asynkrona mekanismen. Future<T> är ett kontrakt för att ta emot ett värde av typ T i framtiden. Future kan vara i ett av tre tillstånd: unresolved (operationen körs), resolved with value (slutförd framgångsrikt) eller resolved with error (slutförd med fel). Efter övergång till resolved-tillståndet ändras inte Future.
Promise i JavaScript är motsvarigheten till Darts Future, men med ett rikare API. Promise tar emot en executor — en funktion med parametrarna resolve och reject. Statiska metoder Promise.all, Promise.race, Promise.allSettled gör det möjligt att kombinera flera promises. Moderna applikationer använder async/await-syntax ovanpå Promise.
Future fungerar baserat på event loop — händelseloopen som bearbetar asynkrona operationer utan att blockera huvudtråden. När en asynkron funktion anropas (t.ex. http.get) returnerar den omedelbart en Future. Den faktiska begäran utförs i bakgrunden medan event loopen fortsätter att bearbeta andra händelser. Efter att operationen slutförts går Future till resolved-tillståndet och then anropas.
Event loop är den viktigaste mekanismen som Dart och JavaScript är byggda på. Event loopen upprätthåller två köer: microtask queue (korta uppgifter som körs före nästa händelse) och event queue (IO-händelser, timers). Future.then placerar callbacken i microtask queue, Future.microtask — prioriterad exekvering före nästa bildruta.
Then()-kedjor möjliggör sekventiell bearbetning av asynkrona operationsresultat utan callback hell. Varje then() tar emot resultatet från föregående steg och returnerar en ny Future. catchError() i slutet av kedjan bearbetar eventuella fel som uppstått i något steg. Detta gör asynkron kod linjär och läsbar.
I Java utökar CompletableFuture konceptet Future/Promise. Metoden supplyAsync() startar en asynkron uppgift i ForkJoinPool.commonPool(). thenApply() transformerar resultatet, thenCompose() — vecklar upp en nästlad CompletableFuture. exceptionally() bearbetar felet genom att returnera ett standardvärde. allOf() och anyOf() fungerar som Promise.all och Promise.race i JavaScript. CompletableFuture stöder manuell slutföring via complete() och completeExceptionally() — detta är motsvarigheten till Promise resolve/reject.
Promise är ett kontrakt med ett av tre tillstånd: pending (väntar), fulfilled (slutförd framgångsrikt) eller rejected (slutförd med fel). Efter övergång till fulfilled eller rejected tillstånd ändras Promise aldrig — detta garanterar oföränderligheten av resultatet för alla konsumenter. Metoden .then() anropas asynkront efter övergång till valfritt slutfört tillstånd.
Promise.all väntar på att alla skickade promises ska slutföras och returnerar en array med resultat i samma ordning. Om en promise slutfördes med fel — går hela Promise.all till rejected. Promise.race returnerar resultatet av den första slutförda promise (framgång eller fel). Promise.allSettled väntar på alla promises oavsett fel — returnerar status för varje.
Chaining — den främsta fördelen med Promise jämfört med callback. Varje .then() returnerar en ny Promise, vilket möjliggör byggande av kedjor av godtycklig längd. Ett fel i någon länk i kedjan sprids till närmaste .catch(). Metoden finally() kör kod efter att kedjan slutförts oavsett resultat — för rensning av resurser.
Första exemplet — skapa en Future via en async-funktion och bearbetning via then/catchError:
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 1))
return "Data laddade"
}
fetchData()
.then((result) => print(result))
.catchError((error) => print("Fel: $error"))
Andra exemplet — kombinera flera Futures via Future.wait:
Future<List<String>> loadAll() async {
final futures = [
fetchFromApi("/users"),
fetchFromApi("/posts"),
fetchFromApi("/comments")
]
final results = await Future.wait(futures)
return results
}
Tredje exemplet — Promise i JavaScript med manuell skapelse och then-kedja:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Klart")
}, 1000)
})
promise
.then(value => console.log(value))
.catch(err => console.error(err))
Future/Promise skiljer sig från callback-stilen genom att det returnerar ett objekt-kontrakt istället för att ta emot en callback-funktion som argument. Callback-stilen leder till nästling (callback hell), medan Future möjliggör byggande av platta then()-kedjor. async/await-syntax gör kod med Future ännu mer linjär, liknande synkron kod.
Future representerar exakt ett asynkront resultat — en emission, varefter Future avslutas. Till skillnad från Observable (Rx, ReactiveX) eller Flow (Kotlin Coroutines) stöder Future inte flera värden över tid. Om du behöver en ström av händelser — använd Stream i Dart, Observable i Rx eller Flow i Kotlin.
CompletableFuture i Java — motsvarigheten till Promise med utökat API: supplyAsync, thenApply, thenCompose, exceptionally. CompletableFuture gör det möjligt att kombinera flera asynkrona operationer via allOf, anyOf, samt ställa in en egen Executor för exekvering. Scala Future använder ExecutionContext för att hantera trådpoolen och stöder komposition via for-comprehension.
I Dart skiljer sig Future-mönstret från JavaScript Promise genom att Dart har strikt typning: Future<String> garanterar typen av det returnerade värdet. Async-funktioner i Dart måste returnera Future och kompilatorn kontrollerar att alla vägar returnerar rätt typ. Future.wait är motsvarigheten till Promise.all — tar emot Iterable<Future<T>> och returnerar Future<List<T>>. Future.delayed och Future.error är praktiska fabriker för testning av asynkrona scenarier.
Future/Promise är implementerat i Python via concurrent.futures.Future och asyncio.Future. concurrent.futures.ThreadPoolExecutor.submit() returnerar en Future där result() kan anropas — ett blockerande anrop. asyncio.Future är en await-kompatibel behållare för asynkront resultat i Asyncio. asyncio.gather() kör flera koroutiner parallellt och returnerar en lista med resultat, liknande Promise.all i JavaScript. Python använder också callback-baserad asyncio.ensure_future och add_done_callback-kedjor för komposition av asynkrona operationer, men i modern kod föredras async/await-syntax med asyncio.Task.
I mobil utveckling används Future aktivt i Flutter-applikationer. Varje nätverksbegäran från paketet http eller dio returnerar en Future. FutureBuilder — en widget som tar emot en Future och en status-snapshot: connectionDone, hasData, hasError. Vid mottagande av data innehåller snapshot.data resultatet av Future. StreamBuilder — motsvarighet för flera värden. FutureBuilder eliminerar manuell hantering av laddningsstatus via setState.
Scala Future använder implicit ExecutionContext — trådpoolen där den asynkrona uppgiften körs. Komposition via map, flatMap, filter fungerar eftersom Future är en monad. for-comprehension gör det möjligt att sekventiellt kombinera flera Futures utan nästling: for { a <- futureA; b <- futureB } yield a + b. Future.sequence fungerar som Promise.all. Återfall vid fel implementeras via recover och recoverWith.
Future/Promise i C++ representeras av klasserna std::future och std::promise från biblioteket <future>. std::async startar en asynkron funktion och returnerar std::future. std::promise möjliggör manuell inställning av värde via set_value() eller fel via set_exception(). Till skillnad från Dart och JavaScript blockerar std::future.get() tråden tills resultatet tas emot — detta är en viktig skillnad som måste beaktas vid design av flertrådade applikationer i C++.
Vid design av API:er som returnerar Future, följ regeln om enda sanningskällan: varje asynkron begäran skapas en gång och cachas via Future.memoize. Om två komponenter begär samma data får de samma Future — detta förhindrar dubbelarbete av begäranden. För timeout, använd Future.timeout (Dart) eller Promise.race med timeout för att garantera att den asynkrona operationen slutförs inom det angivna intervallet.
Retry-mönster i Future implementeras via en rekursiv kedja: vid fel i catch anropas samma asynkrona funktion med fördröjning. Exponential backoff ökar intervallet mellan försök: 1 sek — 2 sek — 4 sek — upp till max 30 sek. I Dart inkapslas detta i ett extension på Future: future.retry(maxRetries: 3, delay: Duration(seconds: 1)). I Scala kombinerar Future.zip två oberoende resultat i en tuple — alternativ till Promise.all för två Futures. Avbrytning (Cancellation) stöds inte i standard Futures, men implementeras via CancellationToken eller AbortController i JavaScript.
Vanliga frågor
Future är en read-only behållare för att läsa ett asynkront resultat via then eller await. Promise är ett write-only kontrakt som tar emot ett värde via resolve() och kopplar det till Future. I Dart och JavaScript är dessa begrepp förenade: Future/Promise är en klass. I Java och Scala är de separata.
Future representerar ett enda asynkront resultat — det emitterar exakt ett värde och avslutas. Observable (Rx) emitterar flera värden över tid — detta är en asynkron ström. Om du behöver ett HTTP-svar — använd Future. Om du behöver en ström av databasändringar — använd Observable eller Stream.
async/await är syntaktisk socker över Future/Promise. Nyckelordet async markerar en funktion som asynkron — den returnerar en Future. await pausar exekveringen tills Future är slutförd, utan att blockera tråden. I Dart, JavaScript, Python och C# har async/await ersatt then-kedjor i de flesta scenarier.
I Dart, använd .catchError() i slutet av kedjan — den fångar undantag i vilket skede som helst. I JavaScript — .catch(). I Dart är även try/await/catch tillgängligt inuti async-funktioner. För återhämtning efter fel, använd .catchError() med att returnera ett standardvärde eller en ny Future.
Promise.all tar emot en array av promises och returnerar en Promise som löses med en array av resultat. Alla promises startas parallellt — detta snabbar upp exekveringen av oberoende operationer (t.ex. laddning av flera filer). Om någon promise avvisas — avvisas hela Promise.all med samma fel.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också