Future/Promise — nedir, asenkron hesaplamalar ve programlama

Yazar: IT Sectr Yayınlanma: 2026-03-17 Okuma süresi: 9 dk

Future/Promise, henüz tamamlanmamış bir işlemin sonucu için bir kapsayıcıyı temsil eden asenkron programlama desenidir. Dart Documentation, 2025'e göre Future, ertelenmiş hesaplamaların salt okunur sonucudur, Promise ise bu sonucu dolduran salt yazılır bir sözleşmedir. Future, Dart, Java, Scala ve C++'da then/catch zincirleri için kullanılır.

Anahtar Noktalar

  • Future — gelecekte kullanılabilir asenkron sonuç için salt okunur kapsayıcı
  • Promise — sonucu alıp Future'a ileten salt yazılır yer tutucu
  • then zincirleri — iç içe callback'ler olmadan asenkron işlemlerin sıralı işlenmesi
  • Future Dart'ta — async/await ve dio, http, shelf kütüphanelerinin temeli
  • Future/Promise — callback desenine alternatif ve async/await sözdiziminin temeli

Future/Promise nedir?

Future/Promise, asenkron bir sonucu iki role ayıran birbirine bağlı nesne çiftidir. Promise sonucu (resolve) veya bir hatayı (reject) yazabilir. Future onu yalnızca okuyabilir — callback'ler (then, catchError) veya await aracılığıyla. Bu ayrım, tüketicinin sonucu değiştiremeyeceğini, yalnızca kullanabileceğini garanti eder.

Dart'ta Future

Dart dili, Future'i ana asenkron mekanizması olarak kullanır. Future<T>, gelecekte T türünde bir değer almak için bir sözleşmedir. Future üç durumdan birinde olabilir: unresolved (işlem devam ediyor), resolved with value (başarıyla tamamlandı) veya resolved with error (hata ile tamamlandı). resolved durumuna geçtikten sonra Future asla değişmez.

JavaScript'te Promise

JavaScript'te Promise, Dart'taki Future'e benzer, ancak daha zengin bir API'ye sahiptir. Promise bir yürütücü (resolve ve reject parametrelerine sahip bir işlev) alır. Statik yöntemler Promise.all, Promise.race, Promise.allSettled, birden çok promise'i birleştirmeye olanak tanır. Modern uygulamalar, Promise üzerinde async/await sözdizimini kullanır.

Future nasıl çalışır

Future, ana iş parçacığını engellemeden asenkron işlemleri işleyen bir olay döngüsü (event loop) temelinde çalışır. Asenkron bir işlev çağrıldığında (örneğin, http.get), hemen bir Future döndürür. Gerçek istek arka planda yürütülürken, event loop diğer olayları işlemeye devam eder. İşlem tamamlandıktan sonra, Future resolved durumuna geçer ve then çağrılır.

Olay döngüsü, Dart ve JavaScript'in üzerine inşa edildiği temel mekanizmadır. Olay döngüsü iki kuyruk tutar: microtask kuyruğu (sonraki olaydan önce yürütülen kısa görevler) ve olay kuyruğu (IO olayları, zamanlayıcılar). Future.then, microtask kuyruğuna bir callback yerleştirir, Future.microtask — sonraki kareden önce öncelikli yürütme.

then() zincirleri, callback cehennemi olmadan asenkron işlem sonuçlarının sıralı olarak işlenmesine olanak tanır. Her then() önceki adımın sonucunu alır ve yeni bir Future döndürür. Zincirin sonundaki catchError(), herhangi bir adımda oluşan herhangi bir hatayı işler. Bu, asenkron kodu doğrusal ve okunabilir hale getirir.

Java'da CompletableFuture

Java'da CompletableFuture, Future/Promise kavramını genişletir. supplyAsync() yöntemi, ForkJoinPool.commonPool() içinde asenkron bir görev başlatır. thenApply() sonucu dönüştürür, thenCompose() iç içe geçmiş bir CompletableFuture'ı açar. exceptionally(), varsayılan bir değer döndürerek bir hatayı işler. allOf() ve anyOf(), JavaScript'teki Promise.all ve Promise.race gibi çalışır. CompletableFuture, complete() ve completeExceptionally() aracılığıyla manuel tamamlamayı destekler — bu, Promise resolve/reject'e benzer.

Promise ve asenkron sözleşme

Promise, üç durumdan birine sahip bir sözleşmedir: pending (beklemede), fulfilled (yerine getirilmiş) veya rejected (reddedilmiş). fulfilled veya rejected durumuna geçtikten sonra Promise asla değişmez — bu, tüm tüketiciler için sonucun değişmezliğini garanti eder. .then() yöntemi, tamamlanmış herhangi bir duruma geçtikten sonra asenkron olarak çağrılır.

Promise.all, iletilen tüm promise'lerin tamamlanmasını bekler ve aynı sırada bir sonuç dizisi döndürür. Bir promise bir hatayla başarısız olursa — Promise.all'ın tamamı rejected durumuna geçer. Promise.race, tamamlanan ilk promise'in sonucunu (başarı veya hata) döndürür. Promise.allSettled, hatalardan bağımsız olarak tüm promise'leri bekler — her birinin durumunu döndürür.

Zincirleme, Promise'in callback'lere göre temel avantajıdır. Her .then() yeni bir Promise döndürerek isteğe bağlı uzunlukta zincirlere izin verir. Zincirin herhangi bir halkasındaki bir hata, en yakın .catch()'e iletilir. finally() yöntemi, sonuçtan bağımsız olarak zincir tamamlandıktan sonra kodu yürütür — kaynak temizliği için.

Future kod örnekleri (Dart)

İlk örnek — async işlevi aracılığıyla Future oluşturma ve then/catchError ile işleme:

dart
Future<String> fetchData() async {
    await Future.delayed(Duration(seconds: 1))
    return "Veriler yüklendi"
}

fetchData()
    .then((result) => print(result))
    .catchError((error) => print("Hata: $error"))

İkinci örnek — birden çok Future'i Future.wait ile birleştirme:

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

Üçüncü örnek — manuel oluşturma ve then zinciri ile JavaScript'te Promise:

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

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

Future vs diğer asenkron desenler

Future/Promise, bir callback işlevini argüman olarak kabul etmek yerine bir sözleşme nesnesi döndürmesiyle callback stilinden farklılık gösterir. Callback stili iç içe geçmeye (callback cehennemi) yol açarken, Future düz then() zincirleri oluşturmaya izin verir. async/await sözdizimi, Future kodunu daha da doğrusal hale getirerek senkron koda benzetir.

Future tam olarak bir asenkron sonucu temsil eder — bir yayım, ardından Future tamamlanır. Observable (Rx, ReactiveX) veya Flow (Kotlin Coroutines)'un aksine Future, zaman içinde birden çok değeri desteklemez. Bir olay akışına ihtiyacınız varsa — Dart'ta Stream, Rx'te Observable veya Kotlin'de Flow kullanın.

Java'da CompletableFuture, genişletilmiş API'siyle Promise'in bir benzeridir: supplyAsync, thenApply, thenCompose, exceptionally. CompletableFuture, allOf, anyOf aracılığıyla birden çok asenkron işlemi birleştirmeye olanak tanır ve ayrıca yürütme için özel bir Executor belirtmeye izin verir. Scala Future, iş parçacığı havuzunu yönetmek için ExecutionContext kullanır ve for-comprehension aracılığıyla birleştirmeyi destekler.

Dart'ta Future deseni, JavaScript Promise'inden farklıdır çünkü Dart katı tür denetimine sahiptir: Future<String> dönüş değerinin türünü garanti eder. Dart'taki async işlevleri bir Future döndürmelidir ve derleyici tüm yolların doğru türü döndürdüğünü kontrol eder. Future.wait, Promise.all'a eşdeğerdir — Iterable<Future<T>> alır ve Future<List<T>> döndürür. Future.delayed ve Future.error, asenkron senaryoları test etmek için kullanışlı fabrika yöntemleridir.

Future/Promise Python'da concurrent.futures.Future ve asyncio.Future aracılığıyla uygulanmıştır. concurrent.futures.ThreadPoolExecutor.submit(), üzerinde result() çağrılabilen bir Future döndürür — engelleyici bir çağrı. asyncio.Future, Asyncio'da asenkron bir sonuç için await uyumlu bir kapsayıcıdır. asyncio.gather(), birden çok coroutine'i paralel olarak çalıştırır ve JavaScript'teki Promise.all'a benzer şekilde bir sonuç listesi döndürür. Python ayrıca asenkron işlemleri birleştirmek için callback tabanlı asyncio.ensure_future ve add_done_callback zincirlerini kullanır, ancak modern kodda asyncio.Task ile async/await sözdizimi tercih edilir.

Mobil geliştirmede, Future Flutter uygulamalarında aktif olarak kullanılır. http veya dio paketinden her ağ isteği bir Future döndürür. FutureBuilder, bir Future ve snapshot durumu (connectionDone, hasData, hasError) alan bir widget'tır. Veri alındığında, snapshot.data Future sonucunu içerir. StreamBuilder, birden çok değer için benzerdir. FutureBuilder, setState aracılığıyla manuel yükleme durumu yönetimini ortadan kaldırır.

Scala Future örtük olarak ExecutionContext kullanır — asenkron görevin yürütüldüğü iş parçacığı havuzu. map, flatMap, filter aracılığıyla birleştirme, Future bir monad olduğu için çalışır. for-comprehension, iç içe geçme olmadan birden çok Future'i sıralı olarak birleştirmeye olanak tanır: for { a <- futureA; b <- futureB } yield a + b. Future.sequence, Promise.all gibi çalışır. Hata durumunda geri dönüş, recover ve recoverWith aracılığıyla uygulanır.

C++'da Future/Promise, <future> kütüphanesindeki std::future ve std::promise sınıflarıyla temsil edilir. std::async, asenkron bir işlev başlatır ve std::future döndürür. std::promise, set_value() aracılığıyla manuel olarak bir değer veya set_exception() aracılığıyla bir hata ayarlamaya olanak tanır. Dart ve JavaScript'in aksine, std::future.get() sonuç alınana kadar iş parçacığını engeller — bu, çok iş parçacıklı C++ uygulamaları tasarlarken dikkate alınması gereken önemli bir farktır.

Future desenleri

Future döndüren API'ler tasarlarken, tek gerçek kaynağı kuralını izleyin: her asenkron istek bir kez oluşturulur ve Future.memoize aracılığıyla önbelleğe alınır. İki bileşen aynı veriyi talep ederse, aynı Future'i alırlar — bu, yinelenen istekleri önler. Zaman aşımı için, asenkron işlemin belirli bir aralıkta tamamlanmasını garanti etmek için Future.timeout (Dart) veya zaman aşımlı Promise.race kullanın.

Future'daki Yeniden Deneme deseni, özyinelemeli bir zincir aracılığıyla uygulanır: catch'te hatada, aynı asenkron işlev bir gecikmeyle çağrılır. Exponential backoff, denemeler arasındaki aralığı artırır: 1 saniye — 2 saniye — 4 saniye — maksimum 30 saniyeye kadar. Dart'ta bu, Future üzerinde bir extension'da kapsüllenmiştir: future.retry(maxRetries: 3, delay: Duration(seconds: 1)). Scala'da Future.zip, iki bağımsız sonucu bir demet halinde birleştirir — iki Future için Promise.all'a bir alternatif. Standart Future'larda iptal desteklenmez, ancak JavaScript'te CancellationToken veya AbortController aracılığıyla uygulanır.

Sıkça Sorulan Sorular

Future ve Promise arasındaki fark nedir?

Future, then veya await aracılığıyla asenkron bir sonucu okumak için salt okunur bir kapsayıcıdır. Promise, resolve() aracılığıyla bir değer kabul eden ve onu Future'a bağlayan salt yazılır bir sözleşmedir. Dart ve JavaScript'te bu kavramlar birleşiktir: Future/Promise tek bir sınıftır. Java ve Scala'da ayrıdırlar.

Future, Observable'dan nasıl farklıdır?

Future tek bir asenkron sonucu temsil eder — tam olarak bir değer yayar ve tamamlanır. Observable (Rx) zaman içinde birden çok değer yayar — asenkron bir akıştır. Bir HTTP yanıtına ihtiyacınız varsa — Future kullanın. Bir veritabanı değişiklik akışına ihtiyacınız varsa — Observable veya Stream kullanın.

async/await nedir ve Future ile nasıl ilişkilidir?

async/await, Future/Promise üzerinde sözdizimsel şekerdir. async anahtar sözcüğü bir işlevi asenkron olarak işaretler — bir Future döndürür. await, iş parçacığını engellemeden Future tamamlanana kadar yürütmeyi duraklatır. Dart, JavaScript, Python ve C#'ta async/await, çoğu senaryoda then zincirlerinin yerini almıştır.

Future zincirinde hatalar nasıl işlenir?

Dart'ta, zincirin sonunda .catchError() kullanın — herhangi bir aşamada istisnaları yakalar. JavaScript'te — .catch(). Dart ayrıca async işlevleri içinde try/await/catch'i de destekler. Hata kurtarma için, varsayılan bir değer veya yeni bir Future döndürerek .catchError() kullanın.

Promise.all nedir ve ne zaman kullanılır?

Promise.all bir promise dizisi alır ve bir sonuç dizisiyle çözümlenen tek bir Promise döndürür. Tüm promise'ler paralel olarak çalışır — bu, bağımsız işlemleri (birden çok dosya yükleme gibi) hızlandırır. Herhangi bir promise reddedilirse — Promise.all'ın tamamı aynı hatayla reddedilir.

Özet

  • Future/Promise — tek bir değer için sözleşmeli asenkron programlama deseni
  • Future — bir işlem sonucunu okumak için salt okunur kapsayıcı
  • Promise — resolve/reject aracılığıyla Future'ı dolduran salt yazılır sözleşme
  • then zincirleri — callback cehennemi olmadan asenkron adımların düz işlenmesi
  • async/await — Future üzerinde sözdizimsel şeker, kodu doğrusal hale getirir
  • Promise.all — birden çok asenkron işlemin paralel yürütülmesi
  • Zaman içinde birden çok değer için Stream veya Observable kullanın, Future değil

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun