Write an example of future using Await.ready and Await.result

admin

7/14/2024
All Articles

  #future using Await.ready #Scala Future vs Await, #Await.ready vs #Await.result, #Handling Futures in Scala

Write an example of future using Await.ready and Await.result

Write an example of future using Await.ready and Await.result

In Scala, asynchronous programming is a cornerstone for building efficient and scalable applications. The Future construct enables developers to perform computations without blocking the main thread, offering a seamless way to handle concurrency. However, when working with futures, there are instances where you need to wait for their completion. This is where Await.ready and Await.result come into play.
Both of these methods allow you to block the current thread until a future completes or a specified timeout is reached. While they share similarities, understanding their differences is critical for writing robust, error-free Scala code.

 


Why Use Await in Scala?

Before diving into the specifics of Await.ready and Await.result, it’s important to understand the role of Await. In asynchronous programming, futures execute tasks in parallel, which means you cannot directly access the result of a computation until it completes. Sometimes, you need to block the execution and wait for the outcome—either for debugging, testing, or certain critical scenarios.

Await offers two methods for this purpose:

  • Await.result: Returns the result of the completed future.
  • Await.ready: Waits for the future to complete but does not return its result directly.

Key Differences Between Await.ready and Await.result

Let’s break down the differences in terms of functionality, use cases, and behavior:

Feature Await.result Await.ready
Return Type The result of the future (e.g., success or failure). The completed Future.
Exception Handling Throws exceptions if the future fails. Does not throw exceptions directly.
Use Case When you need the future’s result immediately. When you want to inspect the future’s state after completion.
Blocking Both block until the future completes or timeout occurs. Both block until the future completes or timeout occurs.

Practical Example: Await.result and Await.ready in Action

Here’s an example to illustrate how these methods work:

Code Example:

import scala.concurrent.Future

import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.util.{Failure, Success}
import scala.concurrent.duration._
import scala.concurrent.Await
object FutureDemo{
 def main(args: Array[String]): Unit = {

      val future = Future { 10 }
       val future2 = Future { 11 }
       val lst= Future {List(1,2,3)}

    try {
      val result = Await.result(future, 2.seconds)
      val result1 = Await.result(future2, 2.seconds)
      val result3 =Await.result(lst,2.seconds)
      println(result+result1)
      print(result3.map(i=>i*2))
    } catch {
      case e: TimeoutException => println("The operation timed out")
    }

 }
}

Explanation of the Example

  1. Await.result:

    • Retrieves the result of the futures (future1, future2, and listFuture) after they complete.
    • If a future fails or the specified timeout (2.seconds) expires, an exception is thrown (e.g., TimeoutException).
  2. Await.ready:

    • Waits for future1 to complete and then inspects its state using the value property.
    • The result of the future can be safely extracted using pattern matching, without directly throwing an exception.

When to Use Await.result and Await.ready

Use Await.result:

  • When you need the actual result of the computation.
  • In scenarios where you’re confident that the future will complete successfully within the given timeout.
  • For testing or debugging synchronous behavior.

Use Await.ready:

  • When you only need to ensure the future has completed without necessarily retrieving its result.
  • When you want to handle the state of the future (Success or Failure) explicitly.
  • For safer exception handling and when working with non-blocking patterns.

Conclusion

 

Understanding the distinction between Await.ready and Await.result is essential for writing effective asynchronous Scala code. While both methods block until a future completes, their return types and use cases differ significantly.

  • Use Await.result when you need the future's result or an exception if it fails.
  • Use Await.ready when you want to inspect the future’s state without throwing exceptions.

By leveraging these methods appropriately, you can handle asynchronous operations in Scala with greater flexibility and control.

For more insights into Scala programming and asynchronous patterns, explore our other articles on Oriental Guru's Technical Blogs.