有没有办法将光滑的查询结果保存到新对象中?
这是我的光滑结果,只有一个"对象"在列表中
val result: Future[Seq[ProcessTemplatesModel]] = db.run(action)
结果应映射到ProcessTemplatesModel,因为我想访问像这样的值
process.title
这可能吗?
由于
答案 0 :(得分:2)
TL; DR :您应该尽可能保留上下文。
Future
表示该值将在未来的某个时间给出(这就是我所说的值的上下文)。
使用它的不好方法是阻止你的线程,直到找到这样的值,然后使用它。
更好的方法是告诉你的程序:“一旦找到值(无论何时),用它做点什么”。这是一个延续或回调,并在scala中使用map
和flatMap
实现。
Seq
是您价值的另一个背景。这意味着您实际上有不同的可能值。如果您想确保最多只有一个值,则可以seq.headOption
始终将上下文从Seq
切换为Option
。
使用它的不好方法是取第一个值,而不用检查它是否存在。
更好的方法是告诉你的程序:“无论你有多少价值,都要为每个人做这件事”。
现在,你如何在上下文中工作?您使用Functor和/或Monad运算符:map
,flatMap
。
例如,如果要将函数convertToSomethingElse
应用于上下文的每个元素,只需执行
result.map(list => list.map(process => convertToSomethingElse(process))
你会得到Future[Seq[SomethingElse]]
。
另一个例子,如果你想将结果保存在其他地方,你可能会有一些IO或数据库操作,这可能需要一些时间,并且可能会失败。我们假设您有一个函数save(entity: ProcessTemplateModel): Future[Boolean]
,可以让您保存一个模型。函数将花费一些时间(并且它将在另一个线程中启动)并且可能失败的事实在返回类型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返回的上下文中来完成我们想要的大部分内容。你不应该想要超越它们,因为
map
使用内部上下文时某些函数用于上下文之外的值Option#get
中没有元素,Option
会抛出异常,Await.result(future, duration)
可能会阻止所有计算或抛出异常Future
Action.async
的形式提供