簡體   English   中英

如何處理 Scala 中的嵌套期貨序列函數

[英]How to handle nested Futures Sequence functions in Scala

我想創建一個 function ,它返回成功操縱的一系列期貨的結果。 我遇到的問題是返回類型是 Unit 並且未來的 function 正在完成,而無需等待嵌套的未來序列完成。 我試過不使用 onComplete function 而是使用 map 或 flatMap 但沒有成功。 我也想避免使用 await

class SquareGenerator(){
  //if type is changed to Unit anything that calls this function receives a empty success
  def getSquare() : Future[Int] = Future{
    val sums = List(future1(), future2())

    val results = Future.sequence(sums)

    //compiler throws an error because this is returning a unit
    results.onComplete({ 
      case Success(result) =>{
        val sum = result(0) + result(1)
        sum * sum
      }
    })
  }

  private def future1() : Future[Int] = Future{
    //do something that takes time
    2
  }

  private def future2() : Future[Int] = Future{
    //do something that takes time
    3
  }
}

以后會這樣稱呼

val squareGenerator = new SquareGenerator()
squareGenerator.getSquare().onComplete({
  case Success(result) =>{
    //do something with result
  }
  case Failure(e){//log failure}
})

而不是onComplete你應該這樣做:

results.map{ result => 
                val sum = result(0) + result(1)
                sum * sum
            }.recover { case e => ...
                // write to log, throw e, or return the same type of sum
}

使用map可以轉換Future內部的返回類型,只有成功完成才會返回未來。

這就是為什么您需要添加recover來處理未來失敗的情況。

如果您這樣做,您將不需要 function 開頭的Future ,因為您不需要創建新的Future - 您將使用來自resultsFuture

onComplete產生一個Unit 您想要mapflatMap或其他實際產生值的東西。

  def getSquare() : Future[Int] = {
    val sums = List(future1(), future2())

    val results: Future[List[Int]] = Future.sequence(sums)

    results.map {
      result => 
        val sum = result(0) + result(1)
        sum * sum
    }
  }

使用數組索引是不安全的。 為了安全起見,您可以使用折疊或模式匹配。

    results map {
      case m :: n :: Nil =>
        val sum = m + n
        sum * sum
      case _ =>
        println("did not get 2 numbers!")
        0
    }

只是在這里返回未來

def getSquare : Future[Future[List[Int]]] = Future{
    val sums = List(future1(), future2())
    Future.sequence(sums)
  }

並且,當你調用它時,檢查結果的 onComplete

  squareGenerator.getSquare.onComplete({
    case Success(result) =>
      result.onComplete({
        case Success(result) => {
          val sum = result(0) + result(1)
          val square = sum * sum
          println(square)
        }
      })

    case Failure(e) => {
      //log failure
    }
  })

您應該使用地圖/平面圖或用於理解。

def getSquare() : Future[Int] = 
  for {
    res1 <- future1()
    res2 <- future2()
  } yield {
    val sum = res1 + res2
    sum * sum
  }

for comprehension是 map 和平面圖的方便包裝。 for部分中,您需要將期貨的結果分配給變量,稍后您可以在yield部分中對它們進行操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM