Is there an alternative pattern for having success and failure closures in Scala?
There's nothing wrong with this convention that's similar to what node.js libraries normally do, but I'm just wondering if there's another way to do this in Scala.
for example:
def performAsyncAction(n: BigInt,
success: (BigInt) => Unit,
failure: FunctionTypes.Failure): Unit = {
Then the call to the function
performAsyncAction(10,
{(x: BigInt) =>
/* Code... */
},
{(t: Throwable) =>
e.printStackTrace()
})
Thanks
It sounds like you want a Future
. See the AKKA implementation here.
A Future
is a functional construct that lets you specify a block of code to be executed asynchronously and then you can grab the result once it's completed:
import akka.actor.ActorSystem
import akka.dispatch.Await
import akka.dispatch.Future
import akka.util.duration._
implicit val system = ActorSystem("FutureSystem")
val future = Future {
1 + 1
}
val result = Await.result(future, 1 second)
println(result) // prints "2"
You can specify on-failure behavior with the onFailure
method (there's also onComplete
and onSuccess
):
val future = Future {
throw new RuntimeException("error")
}.onFailure {
case e: RuntimeException => println("Oops! We failed with " + e)
}
// will print "Oops! We failed with java.lang.RuntimeException: error"
But the best part is that Future
s are Monads, so you can create pipelines of asynchronous actions using things like map
and flatMap
:
val f1 = Future { "hello" }
val f2 = f1.map(_ + " world")
val f3 = f2.map(_.length)
val result = Await.result(f3, 1 second)
println(result) // prints "11"
Or use them in for-comprehensions:
val f1 = Future { "hello" }
val f2 = Future { " " }
val f3 = Future { "world" }
val f4 =
for (
a <- f1;
b <- f2;
c <- f3
) yield {
a + b + c
}
val result = Await.result(f4, 1 second)
println(result) // prints "hello world"