如何组合两个 Future[JsArray]?
How can I combine two Future[JsArray]?
我有两个Future[JsArray]
、f1
和f2
,我需要等待两个都完成并得到结果。
如果他们都成功了,最后的结果应该是Success
保存他们内容的总和。如果 then 中至少有一个失败,则最终结果应该是 Failure
.
我该怎么做?
您可以使用 'for' 语法组合期货。类似于:
val f1:Future[Int] = getF1()
val f2:Future[Int] = getF2()
val res:Future[Int] = for (
v1 <- f1;
v2 <- f2
) yield (v1 + v2)
假设 "summing arrays" 你的意思是将它们与 ++
连接起来,你想要做的是:
Future.sequence(Set(getF1,getF2)) map { _ reduce(_ ++ _)}
当且仅当所有未来都成功时,序列才会成功。然后我们通过 ++
-ing 其所有元素来减少结果 Set
。
一个解决方案
为 Future
定义一个 map2
函数:
def map2[A, B, C](fa: Future[A], fb: Future[B])(g: (A, B) => C)
(implicit executor: ExecutionContext): Future[C] =
for {
a <- fa
b <- fb
} yield g(a, b)
定义一个 merge
函数来合并两个 JsArray
(即提取和连接 元素 ,并使用结果创建一个新的 JsArray
):
def merge(array1: JsArray, array2: JsArray): JsArray =
JsArray(array1.elements ++ array2.elements: _*)
注意:您需要类型归属才能将结果 Vector
传递给 JsArray
's apply
method。
通话
map2(f1, f2)(merge)
在 REPL
中试用 运行
scala> import spray.json._
import spray.json._
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> val f1 = Future(JsArray(JsNumber(1), JsNumber(2)))
f1: scala.concurrent.Future[spray.json.JsArray] = List()
scala> val f2 = Future(JsArray(JsNumber(3), JsNumber(4), JsNumber(5)))
f2: scala.concurrent.Future[spray.json.JsArray] = List()
scala> map2(f1, f2)(merge).onComplete(println)
Success([1,2,3,4,5])
直接而简单的解决方案
Future支持zip
操作,非常方便
val f1: Future[JsArray]
val f2: Future[JsArray]
val resultF = f1.zip(f2).map {case (a, b) => a ++ b}
如果 f1
或 f2
失败,resultF
也会失败,与 f1
或 f2
失败相同。
您可以选择删除括号
val resultF = f1 zip f2 map { case (f1Result, f2Result) => f1Result ++ f2Result }
我有两个Future[JsArray]
、f1
和f2
,我需要等待两个都完成并得到结果。
如果他们都成功了,最后的结果应该是Success
保存他们内容的总和。如果 then 中至少有一个失败,则最终结果应该是 Failure
.
我该怎么做?
您可以使用 'for' 语法组合期货。类似于:
val f1:Future[Int] = getF1()
val f2:Future[Int] = getF2()
val res:Future[Int] = for (
v1 <- f1;
v2 <- f2
) yield (v1 + v2)
假设 "summing arrays" 你的意思是将它们与 ++
连接起来,你想要做的是:
Future.sequence(Set(getF1,getF2)) map { _ reduce(_ ++ _)}
当且仅当所有未来都成功时,序列才会成功。然后我们通过 ++
-ing 其所有元素来减少结果 Set
。
一个解决方案
为
Future
定义一个map2
函数:def map2[A, B, C](fa: Future[A], fb: Future[B])(g: (A, B) => C) (implicit executor: ExecutionContext): Future[C] = for { a <- fa b <- fb } yield g(a, b)
定义一个
merge
函数来合并两个JsArray
(即提取和连接 元素 ,并使用结果创建一个新的JsArray
):def merge(array1: JsArray, array2: JsArray): JsArray = JsArray(array1.elements ++ array2.elements: _*)
注意:您需要类型归属才能将结果
Vector
传递给JsArray
'sapply
method。通话
map2(f1, f2)(merge)
在 REPL
中试用 运行scala> import spray.json._
import spray.json._
scala> import scala.concurrent.Future
import scala.concurrent.Future
scala> import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.ExecutionContext.Implicits.global
scala> val f1 = Future(JsArray(JsNumber(1), JsNumber(2)))
f1: scala.concurrent.Future[spray.json.JsArray] = List()
scala> val f2 = Future(JsArray(JsNumber(3), JsNumber(4), JsNumber(5)))
f2: scala.concurrent.Future[spray.json.JsArray] = List()
scala> map2(f1, f2)(merge).onComplete(println)
Success([1,2,3,4,5])
直接而简单的解决方案
Future支持zip
操作,非常方便
val f1: Future[JsArray]
val f2: Future[JsArray]
val resultF = f1.zip(f2).map {case (a, b) => a ++ b}
如果 f1
或 f2
失败,resultF
也会失败,与 f1
或 f2
失败相同。
您可以选择删除括号
val resultF = f1 zip f2 map { case (f1Result, f2Result) => f1Result ++ f2Result }