Home Ask Login Register

Developers Planet

Your answer is one click away!

Tyler February 2016

Pattern for responding with async result

I am trying to get the following example working:

def asyncTest = Action {

    val willBeInt = Future {
        Thread.sleep(5000)
        100
    }

    willBeInt.onComplete({
        case Success(value) => Ok(s"Value = $value")
        case Failure(e) => Failure(e)
    })
}

But I am getting an error about overloading a method:

Overloaded method value [apply] cannot be applied to  (Unit)

I'm coming from a background in NodeJS and am struggling to figure out how these callbacks are supposed to work while simultaneously returning a result to appease the method signature.

Answers


Dylan February 2016

Think of Action as a function that returns a promise, rather than as a function that accepts a callback. In scala terminology, you'll be returning a Future. Play's internals will be calling onComplete (or something similar) on their own (analagous to a javascript Promise's then function).

Specifically, your compilation error is due to the fact that onComplete returns Unit, when the Action block is expecting you to return a Future. You can use map to transform your willBeInt future into what Play is looking for:

def asynTest = Action.async {
  val willBeInt = Future {
    Thread.sleep(5000)
    100
  }

  // note you will probably need to
  // import scala.concurrent.ExecutionContext.Implicits.global
  // to be able to call `map` here
  willBeInt map { value =>
    Ok(s"Value = $value")
  } recover {
    case e: Throwable => InternalServerError(e.toString)
  }
}

For some extra reading, check out the docs for Future, and the docs for Action

Post Status

Asked in February 2016
Viewed 1,334 times
Voted 5
Answered 1 times

Search




Leave an answer


Quote of the day: live life