使用Future.traverse的Im是執行的順序保證。我的功能fn
必須在下一個元素運行之前調用並完成未來。Future.traverse確保執行的順序
val xs = Seq[T] ???
def fn(t: T): Future[Unit] = ???
Future.traverse(xs)(fn)
感謝,
使用Future.traverse的Im是執行的順序保證。我的功能fn
必須在下一個元素運行之前調用並完成未來。Future.traverse確保執行的順序
val xs = Seq[T] ???
def fn(t: T): Future[Unit] = ???
Future.traverse(xs)(fn)
感謝,
實現:
def traverse[A, B, M[X] <: TraversableOnce[X]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
in.foldLeft(successful(cbf(in))) { (fr, a) =>
val fb = fn(a)
for (r <- fr; b <- fb) yield (r += b)
}.map(_.result())
val fb = fn(a)
創建Future[B]
,然後才與先前創建的未來for (r <- fr; b <- fb) yield (r += b)
組成。所以答案是否定的。沒有執行訂單保證。
斯卡拉2.12實施改變:
def traverse[A, B, M[X] <: TraversableOnce[X]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
in.foldLeft(successful(cbf(in))) {
(fr, a) => fr.zipWith(fn(a))(_ += _)
}.map(_.result())(InternalCallbackExecutor)
但同樣「下一步」創建未來之前(zipWith的第一個參數是「按值調用」)與以前fr
鏈接。
如果您需要依次遍歷那麼就使執行2.11變化不大:
def traverse[A, B, M[X] <: TraversableOnce[X]](in: M[A])(fn: A => Future[B])(implicit cbf: CanBuildFrom[M[A], B, M[B]], executor: ExecutionContext): Future[M[B]] =
in.foldLeft(successful(cbf(in))) { (fr, a) =>
for (r <- fr; b <- fn(a)) yield (r += b)
}.map(_.result())
看起來不像它給我
異步和非阻擋地變換一個TraversableOnce [A]成未來[TraversableOnce [B ]]使用提供的功能A =>未來[B]。這對於執行平行地圖很有用。
它在文檔中沒有具體提及,所以這意味着如果存在更高性能的方法,合同可能會改變。它還提到了「平行地圖」,這是另一個暗示它不太可能保持執行順序。在斯卡拉2.11 traverse
至於其他的答案已經指出的那樣:沒有,traverse
不(一定[1]),應用轉換按順序完成,爲元素。
你可以然而,使一些相當於linearize
也許是這樣的:
import scala.concurrent._
import scala.collection.mutable.Builder
import scala.collection.generic.CanBuildFrom
import language.higherKinds
/**
* Linearize asynchronously applies a given function in-order to a sequence of values, producing a Future with the result of the function applications.
* Execution of subsequent entries will be aborted if an exception is thrown in the application of the function.
*/
def linearize[T, U, C[T] <: Traversable[T]](s: C[T])(f: T => Future[U])(implicit cbf: CanBuildFrom[C[T], U, C[U]], e: ExecutionContext): Future[C[U]] = {
def next(i: Iterator[T], b: Builder[U, C[U]]): Future[C[U]] =
if(!i.hasNext) Future.successful(b.result)
else Future.unit.flatMap(_ => f(i.next()).flatMap(v => next(i, b += v)))
next(s.toIterator, cbf(s))
}
1:你能想象一個同步EC實現順序效果壽。
我沒有達到源代碼的原因是希望在沒有簽名/文檔更改的情況下實現可能會發生變化。 但是,如果信息來源本身說它是無序的,假陽性與假陰性相比是有點模糊的。 –
至於我的文檔需要澄清這種行爲。使用示例並不直接來自方法描述。 – Zernike