【问题标题】:Scala method returning a Future返回 Future 的 Scala 方法
【发布时间】:2023-03-06 02:51:01
【问题描述】:

我使用异步库的以下方法:

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]

我不明白?

【问题讨论】:

    标签: scala promise future


    【解决方案1】:

    'if' 语句的两个分支都应该返回 Option[MyType],如果你使用 async {...} 或 Future[Option[MyType]],那么你不需要 async

    【讨论】:

      【解决方案2】:

      类型Option 不是类型Future,注意if-else 表达式,

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

      【讨论】:

        【解决方案3】:

        你可以这样做,没有承诺和异步

          def myMethod(param: Long, isTru: Boolean): Future[Option[MyType]] = {
        
            if (isTru) {
              doSomething(param).map(res => Some(MyType(param, res)))
            }
            else {
              Future.successful(None)
            }
          }
        

        promise 实际上很少使用

        或者如果您想使用异步,请这样做:

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

        使用异步块的全部意义在于,您从它返回的内容是您想要的某种类型(可能不是 Future),然后将其包装在其中。因此,如果您需要 Option[MyType] 将其返回,它将被包裹在 Future 中,从而为您提供预期的 Future[Option[MyType]]。使 async 有用的是 await() 函数,它将 Future[T] 更改为 T,您可以正常使用,无需映射和其他类似的东西,它有时比嵌套大量 flatMap 更具可读性。

        或者,如果您只是将promise.future 包装在await() 中,就像await(promise.future) 一样,您的代码应该可以工作,但这个解决方案对我来说非常难看。

        【讨论】:

        • 问题是我的 await 调用在 yield 块中,我不能在那个上下文中使用 await。我上面展示的例子只是一个简化版!
        • 那么简单地展示一下,也许我们可以弄清楚一些事情。 Await 肯定有其局限性。
        猜你喜欢
        • 1970-01-01
        • 2017-08-02
        • 1970-01-01
        • 1970-01-01
        • 2013-01-24
        • 2016-08-01
        • 2018-12-15
        • 2012-12-18
        • 2021-05-30
        相关资源
        最近更新 更多