积累期货的最佳方式
Best way to accumulate futures
假设我有一个 return 是 Future 的函数,根据这个函数的结果,我可能需要再次调用它或者我可能 return 立即。我需要将这些结果累积在一个列表中。我想定义一个 return 将此列表作为 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())
但是当然这不会编译,因为在映射中调用 accum() 需要 return 一个 List[Int] 而不是 Future[List[Int]]。正确的做法是什么?
我认为以下内容对您有用,
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 )
始终return来自内部块的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
而不是显式递归函数。
假设我有一个 return 是 Future 的函数,根据这个函数的结果,我可能需要再次调用它或者我可能 return 立即。我需要将这些结果累积在一个列表中。我想定义一个 return 将此列表作为 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())
但是当然这不会编译,因为在映射中调用 accum() 需要 return 一个 List[Int] 而不是 Future[List[Int]]。正确的做法是什么?
我认为以下内容对您有用,
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 )
始终return来自内部块的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
而不是显式递归函数。