joesan
joesan

Reputation: 15385

Scala method returning a Future

The following method that I have that makes use of the async library:

def myMethod(param: Long, isTru: Boolean): Future[Option[MyType]] = async {

  if (isTru) {
    val promise = Promise[Option[MyType]]

    val myFuture = doSomething(param)

    myFuture.onComplete {
      case Success(succ) => {
        promise.success(Some(MyType(param, succ)))
      }
      case Failure(fail) => promise.failure(fail)
    }

    promise.future // fails here
  }
  else {
    None
  }
}

It fails compilation with the error that:

[error] found: scala.concurrent.Future[Option[MyType]]
[error] required: Option[MyType]

which I do not understand?

Upvotes: 0

Views: 962

Answers (3)

elm
elm

Reputation: 20415

Type Option is not type Future, note the if-else expression,

if() {...
  promise.future // fails here
}
else {
  None
}

Upvotes: 1

Łukasz
Łukasz

Reputation: 8663

You could do it like this, without promises and async

  def myMethod(param: Long, isTru: Boolean): Future[Option[MyType]] = {

    if (isTru) {
      doSomething(param).map(res => Some(MyType(param, res)))
    }
    else {
      Future.successful(None)
    }
  }

promises are actually rarely used

or if you want to use async do it like this:

  def myMethod(param: Long, isTru: Boolean): Future[Option[MyType]] = async {

    if (isTru) {
      val myFuture = doSomething(param)
      val myResult = await(myFuture)

      Some(MyType(param, myResult))
    }
    else {
      None
    }
  }

Whole point of using async block is that what you return from it is some type you want (probably not a Future) and then it is wrapped inside one. So if you need Option[MyType] return it, and it will be wrapped inside a Future to give you expected Future[Option[MyType]]. What makes async usefull is the await() function that changes Future[T] to T that you can use normally, without mapping and other things like that, it's sometimes more readable than nesting a lot of flatMaps.

Optionally, your code should work if you just wrap promise.future in await() like this await(promise.future) but this solution is pretty ugly to me.

Upvotes: 6

Nyavro
Nyavro

Reputation: 8866

Both branches of 'if' statement should return either Option[MyType], if you use async {...} or Future[Option[MyType]], then you don't need async

Upvotes: 0

Related Questions