Composição de operações assíncronas
Aprenda a encadear e combinar vários `Futures` usando métodos como `map`, `flatMap` e compreensões `for`.
Composição de operações assíncronas é uma aula grátis de Scala for Backend Engineering & Functional Programming no CoddyKit. Esta é a aula 2 de 3. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Scala for Backend Engineering & Functional Programming, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Scala for Backend Engineering & Functional Programming inclui 3 aulas no total.
Por que encadear operações assíncronas?
Os Futures ajudam a executar tarefas sem bloquear o programa principal. Mas e se o resultado de uma tarefa for necessário para outra, ou se precisarmos combinar os resultados de várias tarefas?
É aí que a composição de Futures se torna útil. Você aprenderá a encadear e combinar essas operações assíncronas, tornando seu código Scala mais poderoso e responsivo.
`map`: transformar o resultado de um Future
O método map é usado quando você tem um Future e deseja transformar seu resultado bem-sucedido em outro valor. A função de transformação fornecida será aplicada assim que o Future for concluído com sucesso.
- Ele sempre retorna um novo
Future. - É ideal para transformações simples e síncronas em um resultado assíncrono.
`map` em ação (código)
Aqui, obtemos um número de um Future e depois o duplicamos usando map. A transformação ocorre somente depois que o Future inicial é concluído.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val originalFuture: Future[Int] = Future {
Thread.sleep(100) // Simulate work
10
}
val doubledFuture: Future[Int] = originalFuture.map(value => value * 2)
val result = Await.result(doubledFuture, 1.second)
println(s"Doubled value: $result")
}
}`flatMap`: encadeando Futures
Às vezes, o resultado bem-sucedido de um Future precisa iniciar outro Future. É aí que flatMap se destaca. Ele "achata" um Future de um Future (Future[Future[T]]) em um único Future[T].
- Use-o quando sua função de transformação retornar um
Future. - Ele é essencial para operações assíncronas sequenciais.
`flatMap` em ação (código)
Buscamos um ID de usuário e depois usamos esse ID para buscar os detalhes do usuário. Cada etapa é uma operação assíncrona que retorna um Future. flatMap garante que elas sejam executadas em sequência.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
def fetchUserId(): Future[Int] = Future {
Thread.sleep(50)
123
}
def fetchUserDetails(userId: Int): Future[String] = Future {
Thread.sleep(100)
s"User $userId details"
}
val userDetailsFuture: Future[String] = fetchUserId().flatMap { userId =>
fetchUserDetails(userId)
}
val result = Await.result(userDetailsFuture, 1.second)
println(s"Details: $result")
}
}`map` vs. `flatMap`: diferença fundamental
É comum confundir map e flatMap. Lembre-se:
map: sua função retorna um valor comum (por exemplo,Int,String).Future[A].map(A => B)resulta emFuture[B].flatMap: sua função retorna outroFuture(por exemplo,Future[Int],Future[String]).Future[A].flatMap(A => Future[B])resulta emFuture[B].
flatMap serve para encadear operações assíncronas, enquanto map serve para transformar um resultado assíncrono de forma síncrona.
Compreensões `for`: encadeamento elegante
As compreensões for do Scala fornecem uma sintaxe clara e legível para encadear operações que envolvem map e flatMap. Elas são apenas açúcar sintático, o que significa que o compilador as transforma em uma série de chamadas a map, flatMap e filter.
Quando você tem várias operações dependentes com Future, as compreensões for fazem o código parecer quase síncrono.
Código de uma compreensão `for`
Este exemplo usa uma compreensão for para encadear a mesma lógica de busca do ID e dos detalhes do usuário que vimos com flatMap. Observe como o código fica mais limpo!
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
def fetchUserId(): Future[Int] = Future {
Thread.sleep(50)
123
}
def fetchUserName(userId: Int): Future[String] = Future {
Thread.sleep(100)
s"Alice (ID: $userId)"
}
val userFuture: Future[String] = for {
id <- fetchUserId()
name <- fetchUserName(id)
} yield name
val result = Await.result(userFuture, 1.second)
println(s"User name: $result")
}
}`zip`: combinando resultados independentes
E se você tiver dois independentes Futures e quiser combinar seus resultados assim que ambos forem concluídos? O método zip é perfeito para isso. Ele recebe outro Future e retorna um novo Future que contém um par (uma Tuple) com os resultados bem-sucedidos de ambos.
Os dois futures são executados simultaneamente, e zip espera que ambos terminem.
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val futureA = Future {
Thread.sleep(100)
"Hello"
}
val futureB = Future {
Thread.sleep(50)
"World"
}
val combinedFuture: Future[(String, String)] = futureA.zip(futureB)
val (greeting, subject) = Await.result(combinedFuture, 1.second)
println(s"$greeting $subject!")
}
}Verificação rápida: compondo Futures
Considere o seguinte trecho de código Scala. Qual será o valor final impresso?
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val f1 = Future { 5 }
val f2 = f1.map(x => x + 2)
val f3 = f2.flatMap(y => Future { y * 3 })
val result = Await.result(f3, 1.second)
println(result)
}
}Recapitulação: encadeando tarefas assíncronas
Você aprendeu maneiras poderosas de compor Futures em Scala:
map: transforma o resultado bem-sucedido de umFutureem um novo valor.flatMap: encadeia doisFutures, usando o resultado do primeiro para iniciar o segundo.- compreensões
for: fornecem uma sintaxe clara, semelhante à síncrona, para cadeias deflatMapemap. zip: combina os resultados de doisFutures independentes em uma tupla.
Essas ferramentas são essenciais para criar aplicações assíncronas responsivas e eficientes em Scala!
Perguntas Frequentes
A aula “Composição de operações assíncronas” é grátis?
Sim — o texto completo de “Composição de operações assíncronas” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Scala for Backend Engineering & Functional Programming, atualize para CoddyKit PRO. O curso de Scala for Backend Engineering & Functional Programming inclui 3 aulas no total.
O que vou aprender em “Composição de operações assíncronas”?
Aprenda a encadear e combinar vários `Futures` usando métodos como `map`, `flatMap` e compreensões `for`. Você pratica Scala for Backend Engineering & Functional Programming com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Scala for Backend Engineering & Functional Programming?
Nenhuma experiência prévia é necessária. Scala for Backend Engineering & Functional Programming no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 3.
Quanto tempo leva a aula “Composição de operações assíncronas”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Scala for Backend Engineering & Functional Programming?
Sim. Cada aula de Scala for Backend Engineering & Functional Programming inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Introdução a Futures e Promises
- Composição de operações assíncronas
- Tratamento de erros em Futures