從Java背景來看,我一直在嘗試自學Scala一段時間。作爲其中的一部分,我正在做一個小型寵物項目,公開一個HTTP端點,將一輛車的registration number
與owner
對接並返回狀態。從Scala未來完成中返回價值
爲了給出更多的上下文,我使用Slick作爲FRM,它異步執行數據庫操作並返回Future
。 根據這個Future的輸出,我想設置status
變量返回給客戶端。
這裏,是代碼
def addVehicleOwner(vehicle: Vehicle): String = {
var status = ""
val addFuture = db.run((vehicles returning vehicles.map(_.id)) += vehicle)
addFuture onComplete {
case Success(id) => {
BotLogger.info(LOGTAG, s"Vehicle registered at $id ")
status = String.format("Registration number - '%s' mapped to owner '%s' successfully", vehicle.registration,
vehicle.owner)
println(s"status inside success $status") //--------- (1)
}
case Failure(e: SQLException) if e.getMessage.contains("SQLITE_CONSTRAINT") => {
status = updateVehicleOwner(vehicle)
BotLogger.info(LOGTAG, s"Updated owner='${vehicle.owner}' for '${vehicle.registration}'")
}
case Failure(e) => {
BotLogger.error(LOGTAG, e)
status = "Sorry, unable to add now!"
}
}
exec(addFuture)
println(s"Status=$status") //--------- (2)
status
}
// Helper method for running a query in this example file:
def exec[T](sqlFuture: Future[T]):T = Await.result(sqlFuture, 1 seconds)
這是在Java中相當簡單。使用Scala時,我面臨以下問題:
- 預期值在(1)處打印,但(2)總是打印空字符串,並且方法返回的是相同的。有人能解釋爲什麼嗎?
我甚至試圖將
var status
標記爲@volatile var status
,它仍然評估爲空字符串。我知道,以上並不是我在靜音狀態下做事的功能方式。爲這種情況編寫代碼的乾淨方式是什麼?
- 幾乎所有我能找到的例子都描述瞭如何映射
Success
的結果或者通過執行println
來處理Failure
。我想做的比這更多。 - 什麼是我可以參考的小項目的一些很好的參考?特別是,遵循TDD。
首先要注意的是,您正在等待addFuture,但它是通過'onComplete'創建的實際上會改變'status'的未來。這可能是您的println沒有達到您的期望的原因。但是,由於各種文檔中提到的所有原因,如果您發現自己在測試之外使用Await.result,您可能錯過了期貨的本質。也許你只是在將來返回狀態值本身(而不是改變外部變量),並且只是通過這個未來,直到有人真正需要結果。 –