2015-09-28 4 views
0

Следующий метод, который я имею, что делает использование библиотеки асинхронном:метод Scala возвращает будущее

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 
    } 
} 

В нем не компиляции с ошибкой, что:

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

, которые я не понимаю?

ответ

6

Вы могли бы сделать это так, без обещаний и асинхронного

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

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

ПРОМИСА эс фактически редко используется

или если вы хотите использовать асинхронный сделать это следующим образом:

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 
    } 
    } 

Всего смыслом использования асинхронного блока является то, что вы возвращаетесь из него какого-то типа вы хотите (вероятно, не Будущее), а затем он обернут внутри одного. Поэтому, если вам нужно Option[MyType], верните его, и он будет завернут в будущее, чтобы вы ожидали Future[Option[MyType]]. То, что делает async полезным, является функцией await(), которая меняет Future[T] на T, которую вы можете использовать обычно, без сопоставления и т. Д. Это иногда более читаемо, чем вложение множества плоских карт.

Возможно, ваш код должен работать, если вы просто оберните promise.future в await() вот так await(promise.future), но это решение довольно уродливо для меня.

+0

Проблема в том, что мои ожидания ждут в блоке доходности, и я не могу использовать ожидание в этом контексте. Пример, который я показал выше, - это просто упрощенная версия! – sparkr

+1

хорошо, тогда показывают неудовлетворительные и, возможно, мы можем что-то понять. Ожидание, безусловно, имеет свои ограничения. –

+0

вот он - http://stackoverflow.com/questions/32823943/scala-synchronising-asynchronous-calls-with-future – sparkr

0

Обе ветви «если» заявление должно возвращать либо вариант [MyType], если вы используете асинхр {...} или будущее [Опция [MyType]], то вам не нужно асинхронной

+0

Не работает! – sparkr

1

Тип Option не тип Future, обратите внимание на выражение if-else,

if() {... 
    promise.future // fails here 
} 
else { 
    None 
} 
Смежные вопросы