如果我将它封装在商品函数中,Scala promise 将不起作用

Scala promise does not work if I encapsulate it in a commodity function

我有我在喷雾处理器中使用的代码

 get {

        def callService = {
          val p = Promise[Option[DocumentRef]]
          val fut = p.future
          archiveService.getByHash(ZeroHash, {
            result => p success result
          })
          fut
        }


        onComplete(OnCompleteFutureMagnet(callService)){
          case Success(docRef) => {


            val doc = docRef map {
              x => x.title
            } getOrElse "nothing"

            complete("Done with " + doc)
          }

          case Failure(ex) => complete("error ${ex.getMessage}")
        }
      }

所以我有了一个绝妙的主意,编写了以下函数来封装为创建未来所做的工作:

def callback2Future[T](funToCall: (T => Unit) => Any): Future[T] = {

    val p = Promise[T]
    val resultFuture = p future
    def callbacklistener(arg: T): Unit = {
      arg: T => p success arg
    }
    funToCall(callbacklistener)
    resultFuture
  }

并将 onComplete 重组为:

 onComplete(OnCompleteFutureMagnet(callback2Future(archiveService.getByHash(ZeroHash, _: Option[DocumentRef] => Unit)))) {
          case Success(docRef) => {
...
}

在 callservice 的原始实现中,它工作得很好(吞吐量也很大),在 callback2Future 实现中我得到了永远的等待,它最终超时了。他们对我来说似乎是一样的,谁能找出错误?

我认为您的问题是由于 Scala 臭名昭著的自动单元特性引起的。你的函数:

def callbacklistener(arg: T): Unit = {
  arg: T => p success arg
}

可能会被解释为:

def callbacklistener(arg: T): Unit = {
  { arg: T => p success arg }
  ()
}

你真正想要的可能是:

def callbacklistener(arg: T): Unit = p success arg

明确地说,在您的实现中,您定义了一个函数 callbackListener,return 类型为 Unit;在此函数的主体中,您有一个表达式 { arg: T => p success arg },其值是 T => Unit 类型并被丢弃; Scala 编译器随后会在您的代码中放置一个空闲的 (),因为 callbackListener 的 return 类型应该是 Unit