[英]Scala Futures Returning Empty List after Await
我有一个执行以下操作的程序:
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()
。 任何建议都会有很大帮助!
混合可变集合和并发不是一个好主意。 考虑重构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} )
你必须使用理解。 基本上首先你必须阅读列表并在yield中,你必须一一调用函数并等待未来通过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)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.