我正在将代码从同步样式迁移到异步样式。问题非常简单:调用一系列函数,并使用第一个函数停止返回非错误结果(返回该值,否则返回最后一个计算值)。我开始时:
def find(fs: Seq[Function0[Int]], result: Int = -1): Int = {
if (fs.isEmpty) result
else {
val res = fs.head()
if (res != 0) res
else find(fs.tail, res)
}
}
但是,如果函数变为异步(即返回Future [Int]),我无法获得正确的调用。例如,
def ffind(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = {
if (ffs.isEmpty) result
else ffind(ffs.tail, ffs.head())
}
效果很好,但无论返回值如何,它都会评估所有函数。但是类似的东西:
def findBad(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = {
if (ffs.isEmpty) result
else {
ffs.head() map { res =>
if (res != 0) res
else findBad(ffs.tail, Future(res))
}
}
}
不进行类型检查。有什么建议?我们可以假设一个函数的每个调用都很昂贵,所以没有一个函数应该调用两次,也不应该在第一个函数调用之后调用。按顺序打电话。 TIA
答案 0 :(得分:1)
这就是为什么它不进行类型检查:findBad
会返回Future[Int]
,但会将res
映射到findBad
的调用中在Future[Future[Int]]
中。您需要将map
更改为flatMap
。请注意,现在您还需要将res
从第一个条件(如果res!= 0)包装到Future
中,以便两个分支都返回Future
。这是代码:
ffs.head() flatMap { res =>
if (res != 0) Future.succesful(res)
else findBad(ffs.tail, Future(res))
}
BTW如果你想要全部运行它们并返回先完成的任何一个,忽略所有其余的,那么它有点不同的问题(参见here),但是你说每个函数调用都很昂贵所以我怀疑你正在做什么。