【问题标题】:Get Future objects from Future Options in Scala从 Scala 中的未来选项获取未来对象
【发布时间】:2017-03-29 20:03:45
【问题描述】:

我是从 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]]

【问题讨论】:

    标签: scala functional-programming future playframework-2.3 scala-option


    【解决方案1】:

    尝试只使用getDocumentByID返回的来自Future的Somes collect

    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
    

    一般建议

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

    【讨论】:

    • 我刚刚这样做了,但Ok(views.html.results(documents.flatten)) 行中有错误。它说:type mismatch, expected: Array[Document], actual: Array[Nothing]
    • @Ken remove flatten
    • 当我删除它时仍然有错误:Type mismatch, expected: Array[Document], actual: mutable.ArrayOps[Document]
    • @ken documents的类型是什么
    • documents 只是map 构造中使用的变量
    猜你喜欢
    • 1970-01-01
    • 2016-03-02
    • 2017-06-24
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多