Future/Promise — hələ tamamlanmamış əməliyyatın nəticəsi üçün konteyner təqdim edən asinxron proqramlaşdırma nümunəsidir. Dart Documentation, 2025-ə görə, Future təxirə salınmış hesablamaların read-only nəticəsidir, Promise isə bu nəticəni dolduran write-only kontraktdır. Future Dart, Java, Scala və C++-da then/catch zəncirləri üçün istifadə olunur.
Əsas məqamlar
Future/Promise — asinxron nəticəni iki rol arasında bölən bir-biri ilə əlaqəli obyektlər cütüdür. Promise nəticəni (resolve) və ya xətanı (reject) yaza bilər. Future onu yalnız oxuya bilər — callback (then, catchError) və ya await vasitəsilə. Bu bölgü istehlakçının nəticəni dəyişə bilməyəcəyinə, yalnız istifadə edə biləcəyinə zəmanət verir.
Dart dili Future-i əsas asinxron mexanizm kimi istifadə edir. Future<T> — gələcəkdə T tipli dəyər almaq üçün kontrakt. Future üç vəziyyətdən birində ola bilər: unresolved (əməliyyat icra olunur), resolved with value (uğurla tamamlandı) və ya resolved with error (xəta ilə tamamlandı). Resolved vəziyyətinə keçdikdən sonra Future dəyişmir.
Promise JavaScript-də Dart Future-inin analoqudur, lakin daha zəngin API ilə. Promise resolve və reject parametrləri olan funksiyanı — ekzekutoru qəbul edir. Promise.all, Promise.race, Promise.allSettled statik metodları bir neçə promisi birləşdirməyə imkan verir. Müasir tətbiqlər Promise üzərində async/await sintaksisindən istifadə edir.
Future event loop — əsas axını bloklamadan asinxron əməliyyatları emal edən hadisə dövrü əsasında işləyir. Asinxron funksiya çağırıldıqda (məsələn, http.get), o dərhal Future qaytarır. Real sorğu arxa planda icra olunur, event loop isə digər hadisələri emal etməyə davam edir. Əməliyyat tamamlandıqdan sonra Future resolved vəziyyətinə keçir və then çağırılır.
Event loop — Dart və JavaScript-in qurulduğu əsas mexanizmdir. Event loop iki növbə saxlayır: microtask queue (növbəti hadisədən əvvəl icra olunan qısa tapşırıqlar) və event queue (IO hadisələri, taymerlər). Future.then callback-i microtask queue-ə yerləşdirir, Future.microtask — növbəti kadradan əvvəl prioritet icra.
then() zəncirləri callback hell olmadan asinxron əməliyyatların nəticələrini ardıcıl emal etməyə imkan verir. Hər then() əvvəlki addımın nəticəsini alır və yeni Future qaytarır. Zəncirin sonunda catchError() hər hansı addımda yaranan istənilən xətanı emal edir. Bu, asinxron kodu xətti və oxunaqlı edir.
Java-da CompletableFuture Future/Promise konsepsiyasını genişləndirir. supplyAsync() metodu ForkJoinPool.commonPool()-da asinxron tapşırıq işə salır. thenApply() nəticəni transformasiya edir, thenCompose() — iç-içə CompletableFuture-i açır. exceptionally() xətanı emal edərək standart dəyər qaytarır. allOf() və anyOf() JavaScript-də Promise.all və Promise.race kimi işləyir. CompletableFuture complete() və completeExceptionally() vasitəsilə əl ilə tamamlamanı dəstəkləyir — bu Promise resolve/reject-in analoqudur.
Promise üç vəziyyətdən biri olan kontraktdır: pending (gözləmə), fulfilled (uğurla tamamlandı) və ya rejected (xəta ilə tamamlandı). Fulfilled və ya rejected vəziyyətinə keçdikdən sonra Promise heç vaxt dəyişmir — bu, bütün istehlakçılar üçün nəticənin dəyişməzliyinə zəmanət verir. .then() metodu istənilən tamamlanmış vəziyyətə keçdikdən sonra asinxron şəkildə çağırılır.
Promise.all bütün ötürülən promislərin tamamlanmasını gözləyir və eyni ardıcıllıqla nəticələr massivi qaytarır. Bir promise xəta ilə tamamlanarsa — bütün Promise.all rejected vəziyyətinə keçir. Promise.race ilk tamamlanan promisin nəticəsini qaytarır (uğur və ya xəta). Promise.allSettled xətalardan asılı olmayaraq bütün promisləri gözləyir — hər birinin statusunu qaytarır.
Chaining — Promise-in callback-dən əsas üstünlüyüdür. Hər .then() yeni Promise qaytarır, ixtiyari uzunluqda zəncirlər qurmağa imkan verir. Zəncirin istənilən halqasında xəta ən yaxın .catch()-ə qədər ötürülür. finally() metodu nəticədən asılı olmayaraq zəncir tamamlandıqdan sonra kodu icra edir — resursların təmizlənməsi üçün.
Birinci nümunə — async-funksiya vasitəsilə Future yaratma və then/catchError ilə emal:
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 1))
return "Məlumatlar yükləndi"
}
fetchData()
.then((result) => print(result))
.catchError((error) => print("Xəta: $error"))
İkinci nümunə — bir neçə Future-in Future.wait vasitəsilə birləşdirilməsi:
Future<List<String>> loadAll() async {
final futures = [
fetchFromApi("/users"),
fetchFromApi("/posts"),
fetchFromApi("/comments")
]
final results = await Future.wait(futures)
return results
}
Üçüncü nümunə — JavaScript-də Promise-in əl ilə yaradılması və then zənciri:
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Hazırdır")
}, 1000)
})
promise
.then(value => console.log(value))
.catch(err => console.error(err))
Future/Promise callback üslubundan onunla fərqlənir ki, arqument kimi geri çağırış funksiyası qəbul etmək əvəzinə obyekt-kontrakt qaytarır. Callback üslubu iç-içəliyə (callback hell) gətirib çıxarır, Future isə düz then() zəncirləri qurmağa imkan verir. async/await sintaksisi Future ilə kodu daha da xətti, sinxron koda bənzər edir.
Future dəqiq bir asinxron nəticəni təmsil edir — bir emissiya, bundan sonra Future bitir. Observable (Rx, ReactiveX) və ya Flow (Kotlin Coroutines)-dan fərqli olaraq, Future zamanda çoxsaylı dəyərləri dəstəkləmir. Hadisə axını lazımdırsa — Dart-da Stream, Rx-də Observable və ya Kotlin-də Flow istifadə edin.
CompletableFuture Java-da — genişləndirilmiş API ilə Promise-in analoqu: supplyAsync, thenApply, thenCompose, exceptionally. CompletableFuture allOf, anyOf vasitəsilə bir neçə asinxron əməliyyatı birləşdirməyə, həmçinin icra üçün öz Executor-u təyin etməyə imkan verir. Scala Future thread hovuzunu idarə etmək üçün ExecutionContext-dən istifadə edir və for-comprehension vasitəsilə kompozisiyanı dəstəkləyir.
Dart-da Future nümunəsi JavaScript Promise-dən onunla fərqlənir ki, Dart ciddi tipizasiyaya malikdir: Future<String> qaytarılan dəyərin tipinə zəmanət verir. Dart-da async funksiyaları Future qaytarmalıdır və kompilyator bütün yolların düzgün tip qaytardığını yoxlayır. Future.wait Promise.all-in ekvivalentidir — Iterable<Future<T>> qəbul edir və Future<List<T>> qaytarır. Future.delayed və Future.error asinxron ssenariləri test etmək üçün rahat fabriklərdir.
Future/Promise Python-da concurrent.futures.Future və asyncio.Future vasitəsilə tətbiq olunub. concurrent.futures.ThreadPoolExecutor.submit() Future qaytarır, onun result() metodunu çağırmaq olar — bloklayan çağırış. asyncio.Future Asyncio-da asinxron nəticə üçün await-uyğun konteynerdir. asyncio.gather() bir neçə korutini paralel işə salır və nəticələr siyahısını qaytarır, JavaScript-də Promise.all kimi. Python həmçinin asinxron əməliyyatların kompozisiyası üçün callback-based asyncio.ensure_future və add_done_callback zəncirlərindən istifadə edir, lakin müasir koddə async/await sintaksisinə asyncio.Task ilə üstünlük verilir.
Mobil tətbiq inkişafında Future Flutter tətbiqlərində fəal şəkildə istifadə olunur. http və ya dio paketindən hər şəbəkə sorğusu Future qaytarır. FutureBuilder — Future və vəziyyət snapshotını qəbul edən vidjetdir: connectionDone, hasData, hasError. Məlumat alındıqdan sonra snapshot.data Future-in nəticəsini ehtiva edir. StreamBuilder — çoxsaylı dəyərlər üçün analoq. FutureBuilder setState vasitəsilə yükləmə vəziyyətinin əl ilə idarə edilməsini aradan qaldırır.
Scala Future ExecutionContext-dən gizli şəkildə istifadə edir — asinxron tapşırığın icra olunduğu thread hovuzu. map, flatMap, filter vasitəsilə kompozisiya Future-in monada olması sayəsində işləyir. for-comprehension bir neçə Future-i iç-içə olmadan ardıcıl birləşdirməyə imkan verir: for { a <- futureA; b <- futureB } yield a + b. Future.sequence Promise.all kimi işləyir. Xəta zamanı fallback recover və recoverWith vasitəsilə həyata keçirilir.
Future/Promise C++-da <future> kitabxanasından std::future və std::promise sinifləri ilə təmsil olunur. std::async asinxron funksiyanı işə salır və std::future qaytarır. std::promise set_value() vasitəsilə əl ilə dəyər təyin etməyə və ya set_exception() vasitəsilə xəta təyin etməyə imkan verir. Dart və JavaScript-dən fərqli olaraq, std::future.get() nəticə alınana qədər thread-i bloklayır — bu, C++-da çoxthreadli tətbiqlərin layihələndirilməsində nəzərə alınmalı vacib fərqdir.
Future qaytaran API-lərin layihələndirilməsində vahid həqiqət mənbəyi qaydasına əməl edin: hər asinxron sorğu bir dəfə yaradılır və Future.memoize vasitəsilə keşlənir. İki komponent eyni məlumatları tələb edərsə, onlar eyni Future-i alır — bu sorğuların təkrarlanmasının qarşısını alır. Timeout üçün Future.timeout (Dart) və ya timeout ilə Promise.race istifadə edin ki, asinxron əməliyyatın müəyyən edilmiş intervalda tamamlanması təmin olunsun.
Retry nümunəsi Future-də rekursiv zəncir vasitəsilə həyata keçirilir: xəta zamanı catch-də eyni asinxron funksiya gecikmə ilə çağırılır. Exponential backoff cəhdlər arası intervalı artırır: 1 san — 2 san — 4 san — max 30 san. Dart-da bu Future-də extension-da inkapsulasiya olunur: future.retry(maxRetries: 3, delay: Duration(seconds: 1)). Scala Future.zip iki müstəqil nəticəni tuple-da birləşdirir — iki Future üçün Promise.all-a alternativdir. Standart Future-lərdə Cancellation dəstəklənmir, lakin JavaScript-də CancellationToken və ya AbortController vasitəsilə həyata keçirilir.
Tez-tez verilən suallar
Future — then və ya await vasitəsilə asinxron nəticəni oxumaq üçün read-only konteyner. Promise — resolve() vasitəsilə dəyər qəbul edən və onu Future ilə əlaqələndirən write-only kontrakt. Dart və JavaScript-də bu anlayışlar birləşdirilib: Future/Promise bir sinifdir. Java və Scala-da onlar ayrılıb.
Future tək asinxron nəticəni təmsil edir — dəqiq bir dəyər emit edir və bitir. Observable (Rx) zaman ərzində çoxsaylı dəyərlər emit edir — bu asinxron axındır. Bir HTTP cavabı lazımdırsa — Future istifadə edin. Verilənlər bazası dəyişiklik axını lazımdırsa — Observable və ya Stream istifadə edin.
async/await — Future/Promise üzərində sintaktik şəkərdir. async açar sözü funksiyanı asinxron olaraq qeyd edir — o Future qaytarır. await Future tamamlanana qədər icranı dayandırır, thread-i bloklamadan. Dart, JavaScript, Python və C#-da async/await əksər ssenarilərdə then zəncirlərini əvəz edib.
Dart-da zəncirin sonunda .catchError() istifadə edin — o istənilən mərhələdə istisnaları tutur. JavaScript-də — .catch(). Dart-da async funksiyaları daxilində try/await/catch də mövcuddur. Xətadan sonra bərpa üçün .catchError() ilə standart dəyər və ya yeni Future qaytarın.
Promise.all promislər massivi qəbul edir və nəticələr massivi ilə həll olunan bir Promise qaytarır. Bütün promislər paralel işə salınır — bu müstəqil əməliyyatların icrasını sürətləndirir (məsələn, çoxsaylı faylların yüklənməsi). Hər hansı promise rədd edilərsə — bütün Promise.all eyni xəta ilə rədd edilir.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun