Promise
In Scala, a Promise is a writable, single-assignment container which completes a Future. Essentially, Promise and Future are two sides of the same coin: while Future provides a way to read a value that may not yet exist, Promise provides a way to write that value once it becomes available. This mechanism is particularly useful in scenarios where you need to manually complete a Future based on the outcome of some computation or asynchronous operation.
Basic Usage of Promise
Here's how you can create and use a Promise in Scala:
- Creating a Promise
First, you need to import the necessary classes:
import scala.concurrent.{Promise, Future}
import scala.concurrent.ExecutionContext.Implicits.global
Then, create a Promise:
val promise: Promise[Int] = Promise[Int]()
- Obtaining the Future from a Promise
You can obtain a Future associated with a Promise. This Future is completed when the Promise is fulfilled.
val future: Future[Int] = promise.future
- Completing a Promise
A Promise can be completed with a value or an exception. Completing the Promise also completes its associated Future.
// Completing the promise with a value
promise.success(42)
// Alternatively, completing the promise with a failure
// promise.failure(new RuntimeException("Failure"))
- Using the Future
You can work with the Future obtained from a Promise just like any other Future. For example, you can add callbacks to handle completion:
future.onComplete {
case Success(value) => println(s"The result is $value")
case Failure(exception) => println(s"Failed with $exception")
}
Example: Asynchronous Computation
Here's a more concrete example, demonstrating how a Promise can be used to wrap an asynchronous computation, such as a network request:
def asyncNetworkRequest(url: String): Future[String] = {
val promise = Promise[String]()
// Simulate an asynchronous network request
global.execute(() => {
try {
// Simulating request delay
Thread.sleep(1000)
promise.success(s"Response from $url")
} catch {
case e: Exception => promise.failure(e)
}
})
promise.future
}
val url = "http://example.com"
val responseFuture: Future[String] = asyncNetworkRequest(url)
responseFuture.onComplete {
case Success(response) => println(response)
case Failure(exception) => println(s"Request failed: $exception")
}
In this example, asyncNetworkRequest simulates making an asynchronous network request. It uses a Promise to represent the eventual result of the request. The Promise is completed with a success or failure once the simulated request finishes, and the associated Future is used to handle the response.