gpt4 book ai didi

scala - 使用 Scala 在 Play 框架中组合 `Future` 结果

转载 作者:行者123 更新时间:2023-12-04 11:24:56 24 4
gpt4 key购买 nike

我正在尝试为以下 URL 编写 Play Framework 异步操作:

POST /users/:userId/items

我的数据库调用全部返回 Future[...] ,其中 ...Option[A]find方法和 Option[Id]用于创建方法。

我想在尝试创建新项目之前检查 userId 是否存在。我有一个方法 Users.findById(userId)返回 Future[Option[User]] .结果是 Some(User)如果用户存在且 None如果不。 Items.create()还返回 Future[Option[itemId]] .

我正在尝试使用 for 创作一些东西:
for {
user <- Users.findById(userId)
if user.isDefined
} yield {
Items.create(...) map { itemId => Ok(itemId) } getOrElse NotFound
}

我要回 Ok(itemId)如果项目创建成功。我不确定如何处理错误情况。我要回 NotFound如果 userId 无效或无法创建项目(可能字段与数据库中已有的唯一值冲突)。

我不知道在 for 后面放什么结构体。我试过 getOrElse ,但这不能编译,因为 Future没有 getOrElse方法。

理想情况下,我可以处理包含多个要检查的 id 的 URL,例如:
PUT /users/:userId/foo/:fooId/bar/:barId

并确认 userId , fooId , 和 barId在进行更新之前都是有效的。所有这些调用( Users.findByIdFoo.findByIdBar.findById )都将返回 Future[Option[A]] .

最佳答案

这种双重嵌套( FutureOption )似乎每次都能吸引人。如果你能先把东西弄平,事情就会变得容易得多。

在这种情况下,Future已经有一种表示错误条件的方法,它可以包装一个 Exception以及成功值(value),这是您可以使用的东西......

// making this a Singleton avoids the cost of building a stack trace,
// which only happens when an Exception is constructed (not when it's thrown)
object NotFoundException extends RuntimeException("Empty Option")

// The map operation will trap any thrown exception and fail the Future
def squish[T](x: Future[Option[T]]) =
x map { _.getOrElse(throw NotFoundException) }

现在在理解中使用这些压扁的结果要容易得多:
val result = for {
user <- squish(Users findById userId)
itemId <- squish(Items.create(user, ...))
} yield {
Ok(itemId)
} recover {
case NotFoundException => NotFound
}

当然,这将评估为 future 。毕竟这是异步编程:)

NotFoundException 之外的任何异常(exception)情况还是会暴露。

关于scala - 使用 Scala 在 Play 框架中组合 `Future` 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21413561/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com