假设我有一个返回Future的函数,根据此函数的结果,我可能需要再次调用它,否则我可能会立即返回。我需要在列表中累积这些结果。我想定义一个函数,将该列表作为Future返回。我有以下内容:
def foo: Future[Int] { ... }
def accum(i: Future[Int], l: List[Int]): Future[List[Int]] = i.map { i =>
if (i >= max)
l
else
accum(foo, i :: l)
}
def test: Future[List[Int]] = accum(foo, List())
但是当然这不会编译,因为在map中调用accum()需要返回List [Int]而不是Future [List [Int]]。这样做的正确方法是什么?
答案 0 :(得分:1)
始终从内部块返回Future
,然后使用flatMap
:
def accum(i: Future[Int], l: List[Int]): Future[List[Int]] =
i.flatMap { i =>
if (i >= max)
Future.successful(l)
else
accum(foo, i :: l)
}
根据foo
的来源,您可能还需要考虑,例如scalaz的foldLeftM
而不是显式的递归函数。
答案 1 :(得分:0)
我认为以下内容适合您,
def foo: Future[Int] = ???
def accumulate( max: Int, f: () => Future[ Int ], list: List[ Int ] = List[ Int ]() ): Future[ List[ Int ] ] = {
val intFuture = f()
intFuture.flatMap( ( i: Int ) => {
// if future is successfull
if ( i < max ) {
// If value less than max, keep on accumulating more
accumulate( max, f, list :+ i )
}
else {
// If value not less than max, stop accumulating more
// Just wrap the list in future and return
val promiseOfList = Promise[ List[ Int ] ]()
promiseOfList.complete( Success( list ) )
promiseOfList.future
}
} ).fallbackTo( {
// If this computation fails.... stop accumulating
// Just wrap the list in future and return
val promiseOfList = Promise[ List[ Int ] ]()
promiseOfList.complete( Success( list ) )
promiseOfList.future
} )
}
val myListFuture = accumulate( max, foo )