scalaintermediate
Future Async Patterns
Work with Scala Futures: composition, error handling, timeout, retry, and parallel execution.
scalaPress ⌘/Ctrl + Shift + C to copy
import scala.concurrent.*
import scala.concurrent.duration.*
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.{Success, Failure, Try}
// Simulated async operations
def fetchUser(id: Int): Future[String] = Future {
Thread.sleep(100)
if id > 0 then s"User-$id"
else throw RuntimeException(s"Invalid ID: $id")
}
def fetchProfile(name: String): Future[Map[String, String]] = Future {
Thread.sleep(50)
Map("name" -> name, "level" -> "pro")
}
def fetchOrders(userId: String): Future[List[String]] = Future {
Thread.sleep(75)
List(s"$userId-order1", s"$userId-order2")
}
@main def run(): Unit =
// Sequential composition
val sequential = for
user <- fetchUser(1)
profile <- fetchProfile(user)
orders <- fetchOrders(user)
yield (user, profile, orders)
val result = Await.result(sequential, 5.seconds)
println(s"Sequential: $result")
// Parallel execution
val f1 = fetchUser(1)
val f2 = fetchUser(2)
val f3 = fetchUser(3)
val parallel = for
u1 <- f1
u2 <- f2
u3 <- f3
yield List(u1, u2, u3)
println(s"Parallel: ${Await.result(parallel, 5.seconds)}")
// Future.sequence: List[Future[A]] => Future[List[A]]
val futures = (1 to 5).map(fetchUser).toList
val allUsers = Future.sequence(futures)
println(s"All: ${Await.result(allUsers, 5.seconds)}")
// Future.traverse: like sequence + map
val traversed = Future.traverse(List(1, 2, 3))(fetchUser)
println(s"Traversed: ${Await.result(traversed, 5.seconds)}")
// Error handling
val failing = fetchUser(-1)
val recovered = failing.recover {
case e: RuntimeException => s"Fallback: ${e.getMessage}"
}
println(s"Recovered: ${Await.result(recovered, 5.seconds)}")
// recoverWith (returns Future)
val retried = fetchUser(-1).recoverWith {
case _ => fetchUser(1) // retry with valid ID
}
println(s"Retried: ${Await.result(retried, 5.seconds)}")
// Transform
val transformed = fetchUser(1).transform {
case Success(v) => Success(s"Got: $v")
case Failure(e) => Success(s"Error: ${e.getMessage}")
}
println(s"Transformed: ${Await.result(transformed, 5.seconds)}")
// Fallback chain
val fallback = fetchUser(-1)
.fallbackTo(fetchUser(-2))
.fallbackTo(fetchUser(1))
println(s"Fallback: ${Await.result(fallback, 5.seconds)}")
// firstCompletedOf
val race = Future.firstCompletedOf(Seq(
Future { Thread.sleep(200); "slow" },
Future { Thread.sleep(50); "fast" },
Future { Thread.sleep(100); "medium" }
))
println(s"Winner: ${Await.result(race, 5.seconds)}")
// Callback
fetchUser(1).onComplete {
case Success(v) => println(s"Callback: $v")
case Failure(e) => println(s"Callback error: $e")
}
Thread.sleep(200) // wait for callback
// Zip futures
val zipped = fetchUser(1).zip(fetchProfile("Alice"))
println(s"Zipped: ${Await.result(zipped, 5.seconds)}")
// Filter
val filtered = fetchUser(1).filter(_.contains("User"))
println(s"Filtered: ${Await.result(filtered, 5.seconds)}")Use Cases
- Asynchronous API calls
- Parallel execution patterns
- Error recovery and fallback chains
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalaintermediate
Futures and Async Programming
Use Scala Futures for async operations: map, flatMap, recover, sequence, and race patterns.
Best for: Asynchronous API calls
#scala#futures
scalaintermediate
Parallel Processing with Collections
Process data in parallel using parallel collections, Future.traverse, and batched execution.
Best for: Speeding up CPU-bound operations
#scala#parallel
scalaadvanced
Akka Actor System Basics
Build concurrent applications with Akka actors: message passing, behavior switching, and supervision.
Best for: Concurrent message-passing systems
#scala#akka
scalaadvanced
ZIO Fibers and Concurrency
Use ZIO fibers for lightweight concurrency: fork, join, race, parallel operations, and supervision.
Best for: Lightweight concurrent task execution
#scala#zio