作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近读了曼努埃尔伯恩哈特的新书Reactive Web Applications .在他的书中,他指出 Scala 开发人员应该从不 使用 .get
检索可选值。
我想接受他的建议,但我正在努力避免.get
用于理解 Futures 时。
假设我有以下代码:
for {
avatarUrl <- avatarService.retrieve(email)
user <- accountService.save(Account(profiles = List(profile.copy(avatarUrl = avatarUrl)))
userId <- user.id
_ <- accountTokenService.save(AccountToken.create(userId, email))
} yield {
Logger.info("Foo bar")
}
AccountToken.create(user.id.get, email)
而不是
AccountToken.create(userId, email)
.但是,当试图避免这种不良做法时,我收到以下异常:
[error] found : Option[Nothing]
[error] required: scala.concurrent.Future[?]
[error] userId <- user.id
[error] ^
最佳答案
第一个选项
如果你真的想用for
理解你必须把它分成几个for
s,其中每个都使用相同的 monad 类型:
for {
avatarUrl <- avatarService.retrieve(email)
user <- accountService.save(Account(profiles = List(profile.copy(avatarUrl = avatarUrl)))
} yield for {
userId <- user.id
} yield for {
_ <- accountTokenService.save(AccountToken.create(userId, email))
}
Future[Option[T]]
一共使用
Future[T]
可以变成
Failure(e)
哪里
e
是
NoSuchElementException
每当您期待
None
(在您的情况下,是
accountService.save()
方法):
def saveWithoutOption(account: Account): Future[User] = {
this.save(account) map { userOpt =>
userOpt.getOrElse(throw new NoSuchElementException)
}
}
(for {
avatarUrl <- avatarService.retrieve(email)
user <- accountService.saveWithoutOption(Account(profiles = List(profile.copy(avatarUrl = avatarUrl)))
_ <- accountTokenService.save(AccountToken.create(user.id, email))
} yield {
Logger.info("Foo bar")
}) recover {
case t: NoSuchElementException => Logger.error("boo")
}
map
/
flatMap
并介绍中间结果。
关于Scala 对 future 和期权的理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39530213/
我是一名优秀的程序员,十分优秀!