0Pricing
Scala for Backend Engineering & Functional Programming · Leçon

Introduction aux Futures et aux Promises

Comprenez les concepts fondamentaux de `Future` pour les résultats asynchrones et de `Promise` pour leur aboutissement.

Introduction aux Futures et aux Promises est une leçon Scala for Backend Engineering & Functional Programming gratuite sur CoddyKit. Ceci est la leçon 1 sur 3. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Scala for Backend Engineering & Functional Programming, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Scala for Backend Engineering & Functional Programming comprend 3 leçons au total.

Code asynchrone : pourquoi est-ce important ?

En programmation, les tâches peuvent s’exécuter de manière synchrone (les unes après les autres) ou asynchrone (les tâches peuvent commencer sans attendre la fin des précédentes).

La programmation asynchrone est essentielle pour créer des applications réactives qui ne se figent pas en attendant des opérations lentes comme des requêtes réseau ou des interrogations de base de données.

Le problème des appels bloquants

Imaginez que votre programme doive récupérer des données sur Internet. Si cette opération est bloquante, votre programme se met en pause et ne fait rien d’autre jusqu’à l’arrivée des données.

Cela peut entraîner une interface utilisateur « figée » ou des applications côté serveur inefficaces. Nous avons besoin d’un moyen d’effectuer ces tâches en arrière-plan sans interrompre le flux principal.

Découvrir les Future de Scala

Le Future de Scala est un outil puissant pour la programmation asynchrone. Il représente une valeur qui n’est peut-être pas encore disponible, mais qui le sera à un moment ultérieur.

  • Imaginez que vous commandiez un café : vous recevez un reçu (le Future) et pouvez faire autre chose pendant la préparation de votre café.
  • Lorsque le café est prêt, le reçu est « terminé » et associé à votre boisson (le résultat).

Créer votre premier Future

Vous pouvez créer un Future en encapsulant un calcul dans Future { ... }. Ce calcul s’exécutera dans un thread distinct.

Un ExecutionContext est nécessaire pour planifier ces tâches. Nous en utiliserons un global par souci de simplicité.

import scala.concurrent.{Future, ExecutionContext}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object Main extends App {
  println("Starting computation...")

  val f: Future[Int] = Future {
    Thread.sleep(1000) // Simulate a long operation
    42
  }

  f.onComplete {
    case Success(value) => println(s"Result: $value")
    case Failure(e) => println(s"Error: ${e.getMessage}")
  }

  println("Computation started, continuing...")
  // Keep main thread alive for a bit to see Future's result
  Thread.sleep(2000)
}

Comprendre ExecutionContext

Un ExecutionContext est essentiellement un pool de threads dans lequel sont exécutés les calculs asynchrones.

  • Il gère la manière et le moment où les tâches sont exécutées.
  • Pour les exemples rapides, scala.concurrent.ExecutionContext.Implicits.global est souvent utilisé, car il fournit un pool de threads par défaut.
  • Dans les applications réelles, vous pouvez configurer des pools de threads spécifiques afin de mieux contrôler l’utilisation des ressources.

Gérer les résultats d’un Future : onComplete

La méthode onComplete sert à définir ce qui se passe lorsqu’un Future se termine, qu’il réussisse ou qu’il échoue.

Elle prend une fonction qui agit sur un scala.util.Try, pouvant être soit Success(value), soit Failure(exception).

import scala.concurrent.{Future, ExecutionContext}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object Main extends App {
  val futureSuccess = Future { 10 / 2 }
  val futureFailure = Future { 10 / 0 }

  futureSuccess.onComplete {
    case Success(result) => println(s"Success: $result")
    case Failure(e) => println(s"Error: ${e.getMessage}")
  }

  futureFailure.onComplete {
    case Success(result) => println(s"Success: $result")
    case Failure(e) => println(s"Error: ${e.getMessage}")
  }

  Thread.sleep(100) // Allow Futures to complete and print
}

Gestionnaires simplifiés : Success/Failure

Pour les cas plus simples, vous pouvez utiliser onSuccess et onFailure pour gérer uniquement les résultats réussis ou uniquement les erreurs, respectivement.

  • onSuccess prend une fonction pour la valeur obtenue en cas de réussite.
  • onFailure prend une fonction pour l’exception.
  • Ce sont des méthodes pratiques construites au-dessus de onComplete.
import scala.concurrent.{Future, ExecutionContext}
import scala.concurrent.ExecutionContext.Implicits.global

object Main extends App {
  val futureValue = Future { "Hello, Scala!" }

  futureValue.onSuccess { case msg => println(s"Got message: $msg") }
  futureValue.onFailure { case e => println(s"Oops, an error: ${e.getMessage}") }

  val futureError = Future { throw new RuntimeException("Something broke!") }

  futureError.onSuccess { case msg => println(s"Got message: $msg") }
  futureError.onFailure { case e => println(s"Oops, an error: ${e.getMessage}") }

  Thread.sleep(100) // Allow Futures to complete and print
}

Qu’est-ce qu’une Promise Scala ?

Alors qu’un Future est un emplacement réservé en lecture seule pour un résultat, une Promise est un conteneur à écriture unique qui peut être complété par une valeur ou une exception.

  • Une Promise sert à compléter un Future.
  • Vous créez une Promise, récupérez le Future qui lui est associé, puis complétez la Promise lorsque le résultat est prêt.

Compléter une Promise

Vous pouvez compléter une Promise à l’aide de ses méthodes success() ou failure(). Une fois la Promise complétée, le Future qui lui est associé le sera également.

Tenter de compléter une Promise plus d’une fois provoque une erreur.

import scala.concurrent.{Future, Promise, ExecutionContext}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object Main extends App {
  val p = Promise[String]() // Create a Promise that will hold a String
  val f: Future[String] = p.future // Get the Future associated with the Promise

  f.onComplete {
    case Success(value) => println(s"Future completed with: '$value'")
    case Failure(e) => println(s"Future failed with: ${e.getMessage}")
  }

  // Simulate an async operation completing the promise
  Future {
    Thread.sleep(500)
    p.success("Data fetched successfully!") // Complete the Promise
  }

  println("Promise created, waiting for completion...")
  Thread.sleep(1000) // Keep main thread alive to see Future's result
}

Future et Promise ensemble

Future et Promise fonctionnent souvent de concert. Il est courant d’utiliser une Promise lorsque vous devez contrôler manuellement la fin d’un Future, par exemple depuis un système externe ou une ancienne interface de programmation fondée sur des rappels.

Cela vous permet d’intégrer des opérations asynchrones qui ne reposent pas sur les Future au modèle des Future et de les rendre compatibles avec le code fondé sur les Future.

import scala.concurrent.{Future, Promise, ExecutionContext}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Failure, Success}

object Main extends App {
  def performLongTask(data: String): Future[String] = {
    val p = Promise[String]()
    // Simulate an external system or callback-based API
    Future {
      Thread.sleep(700)
      if (data == "fail") p.failure(new Exception("Task failed!"))
      else p.success(s"Processed: $data")
    }
    p.future // Return the Future that will be completed by the Promise
  }

  val task1 = performLongTask("input data")
  task1.onComplete { case Success(res) => println(s"Task 1: $res") case Failure(e) => println(s"Task 1: ${e.getMessage}") }

  val task2 = performLongTask("fail")
  task2.onComplete { case Success(res) => println(s"Task 2: $res") case Failure(e) => println(s"Task 2: ${e.getMessage}") }

  Thread.sleep(1500) // Keep main thread alive for results
}

Vérification rapide : Future ou Promise

Laquelle des affirmations suivantes décrit correctement le rôle de Future et de Promise dans Scala ?

Récapitulatif : Future et Promise

Excellent travail ! Dans cette leçon, vous avez appris les fondamentaux de la programmation asynchrone en Scala :

  • Future : espace réservé pour un résultat qui sera disponible ultérieurement.
  • Promise : conteneur à écriture unique utilisé pour terminer manuellement un Future.
  • ExecutionContext : planifie l’exécution des tâches asynchrones.
  • Comment gérer les résultats d’un Future avec onComplete, onSuccess et onFailure.

Ces concepts sont les briques de base de modèles asynchrones plus complexes !

Questions Fréquemment Posées

La leçon « Introduction aux Futures et aux Promises » est-elle gratuite ?

Oui — le texte complet de « Introduction aux Futures et aux Promises » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Scala for Backend Engineering & Functional Programming, passe à CoddyKit PRO. Le cours Scala for Backend Engineering & Functional Programming comprend 3 leçons au total.

Qu'est-ce que j'apprendrai dans « Introduction aux Futures et aux Promises » ?

Comprenez les concepts fondamentaux de `Future` pour les résultats asynchrones et de `Promise` pour leur aboutissement. Tu pratiques Scala for Backend Engineering & Functional Programming avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Scala for Backend Engineering & Functional Programming ?

Aucune expérience préalable n'est requise. Scala for Backend Engineering & Functional Programming sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 3.

Combien de temps prend la leçon « Introduction aux Futures et aux Promises » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Scala for Backend Engineering & Functional Programming ?

Oui. Chaque leçon Scala for Backend Engineering & Functional Programming inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Introduction aux Futures et aux Promises
  2. Composition d’opérations asynchrones
  3. Gestion des erreurs dans les Futures
← Retour à Scala for Backend Engineering & Functional Programming