在Scala中从Future Options获取Future对象

3

我是从Java转到Scala的,所以函数式编程对我来说还有点难以理解。我正在使用Play框架进行项目开发。我需要查询数据库获取带有id的行,并在HTML模板中显示它们。

以下是我的代码:

 def search(query: String) = Action.async{ request =>
    val result = SearchEngine.searchResult(query)
    val docs = result.map(DocumentService.getDocumentByID(_).map(doc => doc))
    val futures = Future.sequence(docs)
    futures.map{documents =>
      Ok(views.html.results(documents.flatten))
    }
  }  

getDocumentByID 函数返回一个 Future[Options[Document]] 对象,但是我的 results 模板需要 Array[Document]。所以我尝试将 Future[Options[Document]] 转换成 Array[Document],但一直失败。

目前我写的代码是最接近的,但仍然不能编译。以下是错误信息:

Error:(36, -1) Play 2 Compiler: 
    found   : Array[scala.concurrent.Future[Option[models.Document]]]
    required: M[scala.concurrent.Future[A]]
1个回答

3
尝试仅从由getDocumentByID返回的Future中collect仅“Some”。请保留HTML标记。
val docs = result.map { res =>
  val f: Future[Option[Document]] = DocumentService.getDocumentByID(res)
  f.collect { case Some(doc) => doc } 
}.toList

val futures = Future.seqence(docs) //notice that docs is converted to list from array in the previous line

一般建议

不要使用 Array。数组是可变的,它们不会动态增长。 因此,在并发/并行代码中应避免使用 Array。


1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Ken
@Ken 移除 flatten - Nagarjuna Pamu
当我将其删除后仍然出现错误:类型不匹配,期望:Array [Document],实际:mutable.ArrayOps [Document] - Ken
@Ken编辑了答案。请使用上面给出的代码进行检查。 - Nagarjuna Pamu
我也尝试过,并且有所改进,但仍然存在一个错误: Error:(36, -1) Play 2 Compiler: found : Array[scala.concurrent.Future[models.Document]] required: M[scala.concurrent.Future[A]] on the line val futures = Future.sequence(docs)。看起来Future.sequence()期望的是一个“Monad”,而不是“Array”。 - Ken
显示剩余13条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接