简体   繁体   English

我怎样才能结合两个Future [JsArray]?

[英]How can I combine two Future[JsArray]?

I have two Future[JsArray] , f1 and f2 , and I need to wait that both are completed with a result. 我有两个Future[JsArray]f1f2 ,我需要等待两个都完成了结果。

If they both succeed, the final result should be a Success holding the sum of their contents. 如果它们都成功,最终结果应该是Success持有其内容的总和。 If at least one of then fails, the final result should be a Failure . 如果其中至少有一个失败,则最终结果应为Failure

How can I do that? 我怎样才能做到这一点?

You can combine futures using 'for' syntax. 您可以使用'for'语法组合期货。 Something like: 就像是:

val f1:Future[Int] = getF1()
val f2:Future[Int] = getF2()
val res:Future[Int] = for (
  v1 <- f1;
  v2 <- f2
) yield (v1 + v2)

Straight forward and simple solution 直截了当,简单的解决方案

Future supports zip operation which is very handy. Future支持zip操作,非常方便。

val f1: Future[JsArray]
val f2: Future[JsArray]
val resultF = f1.zip(f2).map {case (a, b) =>  a ++ b}

if f1 or f2 fails, resultF will also fail with the same exception of f1 or f2 failure. 如果f1f2失败, resultF也将失败,同样的例外是f1f2失败。

optionally you could remove parenthesis 您可以选择删除括号

val resultF = f1 zip f2 map { case (f1Result, f2Result) => f1Result ++ f2Result }

Assuming that by "summing arrays" you mean concatenating them with ++ , you are looking to do: 假设通过“汇总数组”意味着将它们与++连接,您希望:

Future.sequence(Set(getF1,getF2)) map { _ reduce(_ ++ _)}

The sequence will succeed if and only if all futures succeed. 当且仅当所有期货都成功时,序列才会成功。 Then we reduce the resulting Set by ++ -ing all its elements. 然后我们通过++ -ing所有元素减少结果Set

One solution 一个解决方案

  1. Define a map2 function for Future s: Future s定义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) 
  2. Define a merge function for merging the two JsArray s (ie extracting and concatenating the elements , and use the result to create a new JsArray ): 定义merge函数以合并两个JsArray (即提取和连接元素 ,并使用结果创建新的JsArray ):

     def merge(array1: JsArray, array2: JsArray): JsArray = JsArray(array1.elements ++ array2.elements: _*) 

    Note: you need the type ascription in order to pass the resulting Vector to JsArray 's apply method . 注意:您需要类型归属才能将生成的Vector传递给JsArrayapply方法

  3. Call 呼叫

     map2(f1, f2)(merge) 

Trial run in the REPL 在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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM