Reputation: 1025
I'm looking for a way to turn the following into a non-blocking call:
val (greeting, name) =
if (someCondition) {
("Welcome", Option(""))
} else {
var name = Await.result(userClient.getName(arg), Duration.Inf))
("Hi", name)
}
I'm thinking of doing something along the lines of:
val (greeting, name) =
if (someCondition) {
("Welcome", Option(""))
} else {
for {
name <- userClient.getName(arg)
}
yield {
("Hi", name)
}
}
The issue I'm facing is that the for/yield returns a Future[String] to the name tuple for else statement, but returns a Option[String] for the if statement. I need them both to return an Option. In other words, I need to resolve the future. If I pull the name out of the yield, then it won't be in the same scope and the compiler can't figure out that there's a name in the for.
If this can be done without a for/yield that's okay. Just don't want it to be a blocking call.
Upvotes: 1
Views: 120
Reputation: 32319
The best you can do is
val (greeting, name): (String, Future[Option[String]]) = if (someCondition) {
("Welcome", Future.successful(Some("")))
} else {
("Hi", userClient.getName(arg))
}
You can't convert a Future[Option[String]]
into Option[Future[String]]
without awaiting the Future
; an Option[Future[String]]
knows upfront if it is Some
or None
while Future[Option[String]]
doesn't.
In this case, there is no need for a for
comprehension.
Upvotes: 1