scalaintermediate
Futures and Async Programming
Use Scala Futures for async operations: map, flatMap, recover, sequence, and race patterns.
scalaPress ⌘/Ctrl + Shift + C to copy
import scala.concurrent.{Future, Promise, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*
import scala.util.{Success, Failure}
def fetchUser(id: Int): Future[String] = Future {
Thread.sleep(100)
if id <= 0 then throw RuntimeException(s"Invalid id: $id")
s"User-$id"
}
def fetchOrders(user: String): Future[List[String]] = Future {
Thread.sleep(100)
List(s"$user-order1", s"$user-order2")
}
@main def run(): Unit =
// Basic future
val future = Future {
Thread.sleep(50)
42
}
// Callbacks
future.onComplete {
case Success(v) => println(s"Got: $v")
case Failure(e) => println(s"Failed: ${e.getMessage}")
}
// map and flatMap
val doubled = future.map(_ * 2)
val chained = fetchUser(1).flatMap(fetchOrders)
// for-comprehension
val workflow = for
user <- fetchUser(1)
orders <- fetchOrders(user)
yield (user, orders)
val (user, orders) = Await.result(workflow, 5.seconds)
println(s"$user: $orders")
// Error recovery
val recovered = fetchUser(-1)
.recover { case e: RuntimeException => "default-user" }
println(Await.result(recovered, 5.seconds))
// recoverWith: return another Future
val fallback = fetchUser(-1)
.recoverWith { case _ => fetchUser(1) }
println(Await.result(fallback, 5.seconds))
// Parallel execution
val f1 = fetchUser(1)
val f2 = fetchUser(2)
val f3 = fetchUser(3)
val parallel = for
u1 <- f1 // all started before for-comprehension
u2 <- f2
u3 <- f3
yield List(u1, u2, u3)
println(s"Parallel: ${Await.result(parallel, 5.seconds)}")
// Future.sequence: List[Future] => Future[List]
val futures = (1 to 5).map(fetchUser).toList
val all = Future.sequence(futures)
println(s"All: ${Await.result(all, 5.seconds)}")
// firstCompletedOf: race
val fast = Future { Thread.sleep(50); "fast" }
val slow = Future { Thread.sleep(200); "slow" }
val winner = Future.firstCompletedOf(List(fast, slow))
println(s"Winner: ${Await.result(winner, 5.seconds)}")
// Promise
val promise = Promise[String]()
Future {
Thread.sleep(100)
promise.success("Promise fulfilled")
}
println(Await.result(promise.future, 5.seconds))
Thread.sleep(500) // let callbacks finishUse Cases
- Asynchronous API calls
- Parallel task execution
- Error recovery in async workflows
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
scalaintermediate
Future Async Patterns
Work with Scala Futures: composition, error handling, timeout, retry, and parallel execution.
Best for: Asynchronous API calls
#scala#future
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