Scala 未来的延迟val是否会阻止实际的数据库调用?

Scala 未来的延迟val是否会阻止实际的数据库调用?,scala,future,Scala,Future,我想进行如下查询: 查询特定日期的记录 如果(1)失败,则查询日期范围内的记录,以最后一个日期为准 我现在处理这件事的方式是: 特定于lazy val:Future[Option[QueryResponse]]=//某些数据库调用 延迟val范围:未来[选项[QueryResponse]]= //某些数据库调用返回Future[Seq[QueryResponse]] .map{qrs=> 如果(qrs.nonEmpty)一些(qrs.maxBy(u.date)(uu比较uuo)) 没有别的 }

我想进行如下查询:

  • 查询特定日期的记录
  • 如果(1)失败,则查询日期范围内的记录,以最后一个日期为准
  • 我现在处理这件事的方式是:

    
    特定于lazy val:Future[Option[QueryResponse]]=//某些数据库调用
    延迟val范围:未来[选项[QueryResponse]]=
    //某些数据库调用返回Future[Seq[QueryResponse]]
    .map{qrs=>
    如果(qrs.nonEmpty)一些(qrs.maxBy(u.date)(uu比较uuo))
    没有别的
    }
    为了{
    
    现在,您的代码将执行<代码>特定< /代码>和<代码>范围< /代码>,尽管它们是懒惰的。请考虑下面的简化代码段

      lazy val specific = Future(Some("specific"))
      lazy val range = Future(Some("range"))
    
      (for {
        s <- specific
        r <- range
      } yield {
        (s, r)
      }).foreach(println)
    

    我们看到两者都被执行。理解的性质意味着它们都被声明为懒惰而运行。如果你想“代码>范围<代码>只执行,如果<代码>特定< /代码>不返回结果,那么考虑做一些类似于

    的事情。
    specific.flatMap {
        case Some(v) => Future(Some(v), None)
        case _ => range.map {
          case Some(v) => (None, Some(v))
          case _ => (None, None)
        }
      }.foreach(println)
    
    哪个输出

    (Some(specific),Some(range))
    
    (Some(specific),None)
    
    specific
    
    我们看到的
    范围
    没有运行

    Scalaz将问题简化为

    import scalaz._
    import scalaz.std.scalaFuture.futureInstance
    
    OptionT(specific).orElse(OptionT(range)).map(println)
    
    哪个输出

    (Some(specific),Some(range))
    
    (Some(specific),None)
    
    specific
    

    这意味着
    range
    没有运行。

    这是不对的。
    range
    只有在
    specific
    成功时才会执行。@Tim if specific返回Future(无)范围仍将运行。是的,我看得越多,它就变得越不清晰!我假设数据库故障将使未来的
    失败,但可能它只返回
    None
    。这很巧妙。谢谢。对这是否“正确”有何评论方法?在范围内过滤并查找最新日期是否更有效,因为数据库调用将以任何一种方式进行?我假设,对第一个请求失败的统计可能性进行某种研究,将有助于做出决定。@franklin如果不实际观察它在实际wo中的表现,很难判断rld.我的建议是尝试使用
    范围
    ,如果您发现性能不足,则添加优化。