【问题标题】:Scala Futures Returning Empty List after Await等待后 Scala 期货返回空列表
【发布时间】:2020-06-12 20:41:51
【问题描述】:

我有一个程序执行:

Await.result(Processor.validateEntries(queuedEntries)), Duration.Inf)

validateEntries 方法调用其他一些执行的方法:

val validatedEntries: ListBuffer[Entries] = new ListBuffer[Entries]

for (entry <- queuedEntries) {
checkEntry(entry.name).map(.......... validatedEntries += Entries(...) )
}
Future(validatedEntries.toList)

其中checkEntry 返回Future[Boolean]

def checkEntry(name: String): Future[Boolean] = {
    checkNameAlreadyExists(name).flatMap(exists =>
        buildRequest(exists, name).map(response => {
            if (!response.contains("error")) {
                true
            } else {
                false
            }
        })
    )
}

在执行Await.result 的顶层,我还得到一个空列表:List()。任何建议都会有很大帮助!

【问题讨论】:

  • 能否添加完整的功能?
  • @VimitDhawan 我编辑了以上内容

标签: list scala future


【解决方案1】:

混合可变集合和并发性不是一个好主意。考虑重构checkEntry 以返回,比如Future[Option[Entry]] 而不是Future[Boolean],其中Some 表示验证成功,而None 不成功,然后你可能会做类似

case class Entry(v: Int)
val queuedEntries = List(Entry(1), Entry(2), Entry(3))
def checkEntry(entry: Entry): Future[Option[Entry]] = ???

Future
  .traverse(queuedEntries)(checkEntry)
  .map(_.flatten)

如果保持checkEntry 不变,那么您可以尝试类似

case class Entry(v: Int)
val queuedEntries = List(Entry(1), Entry(2), Entry(3))
def checkEntry(entry: Entry): Future[Boolean] = Future(Random.nextBoolean)

Future
  .traverse(queuedEntries)(checkEntry)
  .map(checkedEntries => checkedEntries zip queuedEntries)
  .map(_.collect { case (validated, entry) if validated => entry} )

【讨论】:

    【解决方案2】:

    你必须用于理解。基本上首先你必须阅读列表,在yield中,你必须一个一个地调用函数并等待future通过yield完成

    package com.vimit.StackOverflow
    
    import scala.concurrent._
    import ExecutionContext.Implicits.global
    
    
    object FutureProblem extends App {
    
    
      val list = List(1, 2, 3)
      val outputList = List()
    
      val result = for {
        value <- list
      } yield {
        for {
          result <- getValue(value).map(res => outputList ++ List(value))
        } yield result
      }
    
      print(result)
    
      def getValue(value: Int) = Future(value)
    
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-03
      • 2020-10-31
      • 1970-01-01
      • 2017-07-30
      • 2013-08-02
      • 2015-08-24
      • 1970-01-01
      • 2013-07-14
      • 1970-01-01
      相关资源
      最近更新 更多