Randomize Randomize - 3 months ago 14
Scala Question

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.

If they both succeed, the final result should be a
Success
holding the sum of their contents. If at least one of then fails, the final result should be a
Failure
.

How can I do that?

Answer

One solution

  1. Define a map2 function for Futures:

    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 JsArrays (i.e. extracting and concatenating the elements, and use the result to create a new 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.

  3. Call

    map2(f1, f2)(merge)
    

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