|
|
|
|
|
by ssmoot
4438 days ago
|
|
async/await and removal of the case-class/tuple 22 field limit are the big ones I think. (edit: the limit is still in effect for Tuple apparently. Only removed for case-classes.) In database (or Actor ask) heavy code dealing with a lot of Futures async/await has the potential to fairly significantly influence code style. for-comprehensions often don't cut it when you're dealing with a Future[Option[User]] and need to pull in their assigned roles from a Future[Seq[Role]]. val userOption = db.get(userId) flatMap {
case None => Future.successful(None)
case Some(user) =>
Future.sequence {
user.roleIds map(db.get(_))
} map { roles =>
Some(user.copy(roles = roles.flatten))
}
}
vs: val userOption = async {
for {
user <- await(db.get(userId))
roles = await(Future.sequence(user.roleIds map(db.get(_))))
} yield user.copy(roles = roles.flatten)
}
Or something like that anyways. |
|
If you aren't familiar with Monad Transformers, yes, it can be tricky. However it's trivial using an Option monad transformer (OptionT[Future,A]]) to have the same semantics.
Look at http://github.com/scalaz for already built Monad Transformers (Either/State/Option/Writer) that will work with the standard lib Future along with tons of other goodies. I actually actively dislike the async stuff as it gives you another way of doing the same thing, at a less powerful abstraction.