scala 将光滑的结果保存到新对象中
scala save slick result into new object
有没有办法将灵活查询的结果保存到新对象中?
这是我的圆滑结果,列表中只有一个"object"
val result: Future[Seq[ProcessTemplatesModel]] = db.run(action)
结果应该映射到 ProcessTemplatesModel,因为我想访问这样的值
process.title
这可能吗?
谢谢
TL;DR: 你应该尽可能长时间地保留上下文。
Future
表示该值将在未来某个时间给出(这就是我所说的值的某些上下文)。
使用它的糟糕方法是阻塞您的线程,直到找到该值,然后再使用它。
更好的方法是告诉你的程序:"Once the value is found (whenever that is), do something with it"。这是一个延续,或回调,并在 scala 中用 map
和 flatMap
实现。
Seq
是您的价值的另一个背景。这意味着您实际上有不同的可能值。如果你想确保你最多有一个值,你总是可以做 seq.headOption
将上下文从 Seq
切换到 Option
.
使用它的糟糕方法是直接取第一个值而不去检查它是否存在。
更好的方法是告诉你的程序:"No matter how many values you have, do this for each of them"。
现在,你如何在上下文中工作?您使用 Functor and/or Monad 运算符:map
、flatMap
.
例如,如果您想将函数 convertToSomethingElse
应用于上下文的每个元素,只需执行
result.map(list => list.map(process => convertToSomethingElse(process))
你会得到一个 Future[Seq[SomethingElse]]
。
再比如,如果你想把结果保存到别处,你可能会有一些IO,或者数据库操作,这可能需要一些时间,而且可能会失败。我们假设您有一个函数 save(entity: ProcessTemplateModel): Future[Boolean]
可以让您保存您的模型之一。该函数将花费一些时间(并且它将在另一个线程中启动)并且可能失败的事实在 return 类型 Future[Boolean]
中可见(Boolean
在这里并不重要,它是事实上,我们再次拥有重要的 Future
上下文)。
在这里,您必须执行(假设您只想保存列表中的第一个元素):
val savedFirstResult: Future[Option[ProcessTemplatesModel]] = result.flatMap {list =>
Future.traverse(list.headOption){ process => //traverse will switch the Future and Option contexts
save(process)
}
}
因此,如您所见,我们可以通过留在 Slick returned 的上下文中来完成我们想做的大部分事情。你不应该想离开他们,因为
- 大多数情况下,当您
map
在上下文中使用一些函数来获取上下文外的值时,大多数时候没有必要这样做
- 提取方法大多数时候是不安全的:
Option#get
如果没有元素在Option
中会抛出异常,Await.result(future, duration)
可能会阻止所有计算或抛出异常
- Play 中的响应!可以在控制器中作为
Future
s 给出,使用 Action.async
有没有办法将灵活查询的结果保存到新对象中?
这是我的圆滑结果,列表中只有一个"object"
val result: Future[Seq[ProcessTemplatesModel]] = db.run(action)
结果应该映射到 ProcessTemplatesModel,因为我想访问这样的值
process.title
这可能吗?
谢谢
TL;DR: 你应该尽可能长时间地保留上下文。
Future
表示该值将在未来某个时间给出(这就是我所说的值的某些上下文)。
使用它的糟糕方法是阻塞您的线程,直到找到该值,然后再使用它。
更好的方法是告诉你的程序:"Once the value is found (whenever that is), do something with it"。这是一个延续,或回调,并在 scala 中用 map
和 flatMap
实现。
Seq
是您的价值的另一个背景。这意味着您实际上有不同的可能值。如果你想确保你最多有一个值,你总是可以做 seq.headOption
将上下文从 Seq
切换到 Option
.
使用它的糟糕方法是直接取第一个值而不去检查它是否存在。
更好的方法是告诉你的程序:"No matter how many values you have, do this for each of them"。
现在,你如何在上下文中工作?您使用 Functor and/or Monad 运算符:map
、flatMap
.
例如,如果您想将函数 convertToSomethingElse
应用于上下文的每个元素,只需执行
result.map(list => list.map(process => convertToSomethingElse(process))
你会得到一个 Future[Seq[SomethingElse]]
。
再比如,如果你想把结果保存到别处,你可能会有一些IO,或者数据库操作,这可能需要一些时间,而且可能会失败。我们假设您有一个函数 save(entity: ProcessTemplateModel): Future[Boolean]
可以让您保存您的模型之一。该函数将花费一些时间(并且它将在另一个线程中启动)并且可能失败的事实在 return 类型 Future[Boolean]
中可见(Boolean
在这里并不重要,它是事实上,我们再次拥有重要的 Future
上下文)。
在这里,您必须执行(假设您只想保存列表中的第一个元素):
val savedFirstResult: Future[Option[ProcessTemplatesModel]] = result.flatMap {list =>
Future.traverse(list.headOption){ process => //traverse will switch the Future and Option contexts
save(process)
}
}
因此,如您所见,我们可以通过留在 Slick returned 的上下文中来完成我们想做的大部分事情。你不应该想离开他们,因为
- 大多数情况下,当您
map
在上下文中使用一些函数来获取上下文外的值时,大多数时候没有必要这样做 - 提取方法大多数时候是不安全的:
Option#get
如果没有元素在Option
中会抛出异常,Await.result(future, duration)
可能会阻止所有计算或抛出异常 - Play 中的响应!可以在控制器中作为
Future
s 给出,使用Action.async