2017-08-23 39 views
-1

在我的後端控制器功能,我有以下代碼:如何解決Scala的異步行爲

def getContentComponents = Action.async { 
    contentComponentDTO.list().map { contentComponentsFuture => 
     contentComponentsFuture.foreach(contentComponentFuture => 
     contentComponentFuture.typeOf match { 
      case 5 => contentComponentDTO.getContentComponentText(contentComponentFuture.id.get).map(text => { 
      contentComponentFuture.text = text.text 
      println(contentComponentFuture.text) 
      }) 

     } 
    ) 
     Ok(Json.toJson(contentComponentsFuture)) 
    } 
    } 

的問題是,上面的東西完成之前OK()被調用。有沒有一種智能的方法可以等到foreach完成?

謝謝

這是兩個不同的問題與不同的問題!因此,這是兩個問題看起來類似的原因

+0

這遠不是這個函數的第一個問題上。我強烈建議先閱讀Scala和Play教程,然後再問 – cchantep

+0

[scala Returns Future \ [Unit \]而不是Future \ [ContentComponentModel \]]的可能重複(https://stackoverflow.com/questions/45835922/scala- return-futureunit-instead-of-futurecontentcomponentmodel) – cchantep

回答

0

有兩種方法,你可以採取,但在這之前,讓我們回顧你想要做的。

  1. 你有一個項目列表contentComponentsFuture,我假設從數據庫中檢索,這就是爲什麼你會得到未來。
  2. 現在你的contentComponentsFuture是一個可變變量(我強烈建議不要使用,堅持不變數據)有一個需要更新的文本字段。 現在Ok()之前的所有代碼塊都會返回未來,因爲它正在處理將來的列表。所以最簡單的解決方案是在未來做一張地圖並返回結果。未來的地圖只是一個onComplete函數,一旦未來解決就會觸發。因此,代碼會看起來像:

    def getContentComponents = Action.async { 
    val futureResult = contentComponentDTO.list().map { contentComponentsFuture => 
        contentComponentsFuture.map(contentComponentFuture => 
        contentComponentFuture.typeOf match { 
         case 5 => contentComponentDTO.getContentComponentText(contentComponentFuture.id.get).map(text => { 
         contentComponentFuture.text = text.text 
         contentComponentFuture 
         }) 
        } 
    ) 
    } 
        futureResult.map(result => { 
    Future.sequence(result).map(t => Ok(Json.toJson(t)) 
    

    })) }

另一種選擇將是使用Scala的asycn庫:https://github.com/scala/scala-async 賦予一個方便的包裝,這樣你就不需要爲了明確未來地圖,以上與scala異步庫相同的代碼將如下所示:

def getContentComponents = Action.async { 
    Async.async { 
    val result = Async.await(contentComponentDTO.list().map { contentComponentsFuture => 
     contentComponentsFuture.map(contentComponentFuture => 
     contentComponentFuture.typeOf match { 
      case 5 => contentComponentDTO.getContentComponentText(contentComponentFuture.id.get).map(text => { 
      contentComponentFuture.text = text.text 
      contentComponentFuture 
      }) 
     } 
    ) 
    }) 

    Ok(Json.toJson(result)) 
    } 
    } 
+0

謝謝,當我嘗試第一個解決方案時,已經試過了,我收到了以下消息: – Felix

+0

'找不到類型單元的Json串行器。嘗試實現這種類型的隱式寫入或格式.' – Felix

+1

更新了代碼,而不是println返回修改後的變量:contentComponentFuture 因爲println返回單元,所以出現錯誤。嘗試了 – Tawkir