簡體   English   中英

如何在Play Framework 2控制器動作中等待?

[英]How to Await in Play Framework 2 controller action?

我嘗試編寫動作以生成圖片的縮略圖,並向用戶顯示是否尚未生成。 問題是:生成部分異步運行,並在生成部分完成之前顯示部分代碼運行。 我是Scala和Play Framework的新手,無法參加演出。 我已經這樣嘗試過了:

def thumbs(profiletype: String, id: Int, filename: String, extention: String) = Action {
val content = File.getBinaryContent(pathToDir + filename + "." + extention)
content match {
  case Some(c) => Ok(c).as(File.getContentType(extention))
  case _ => val picture = Picture.getById(id)
      picture match {
        case None => NotFound("Page not found")
        case Some(p) => val rslt = Future (p.generateThumbs(pathToDir, profiletype))
          val r=rslt.map(a=>a)
          Await.ready(r, Duration(8, "second"))
            Logger.debug(pathToDir + filename + "." + extention)
            val content = File.getBinaryContent(pathToDir + filename + "." + extention)
            renderBinary(content, File.getContentType(extention))}
          }
}

像這樣沒有運氣

def thumbs(profiletype: String, id: Int, filename: String, extention: String) = Action {
val content = File.getBinaryContent(pathToDir + filename + "." + extention)
content match {
  case Some(c) => Ok(c).as(File.getContentType(extention))
  case _ => val picture = Picture.getById(id)
      picture match {
        case None => NotFound("Page not found")
        case Some(p) => val rslt = Future (p.generateThumbs(pathToDir, profiletype))
          Await.ready(rslt, Duration(8, "second"))
            Logger.debug(pathToDir + filename + "." + extention)
            val content = File.getBinaryContent(pathToDir + filename + "." + extention)
            renderBinary(content, File.getContentType(extention))}
          }
}

在p.generateThumbs完成之前,此等待不起作用並且Logger會記錄日志

您可以返回Future[Result] ,而不是異步生成縮略圖並在等待生成縮略圖之前等待時阻塞(使用Await.readyAwait.result )。

在您的情況下,這看起來像(未經測試):
我還將您的Option模式匹配轉換為mapgetOrElse函數。

def thumbs(
  profiletype: String, id: Int, filename: String, extention: String
) = Action.async { // return an (explicit) asynchronous result
  val filepath = pathToDir + filename + "." + extention
  File.getBinaryContent(filepath)
    .map ( content => 
       // we found the thumbnail, return its content as a Future[Result]
       Future.successful(Ok(content).as(File.getContentType(extention)))
    )
    .getOrElse {
      // we have not found the thumbnail, check if the Picture exists
      Picture.getById(id)
        .map { picture =>
          // we found the Picture, lets generate the thumbnails
          Future(picture.generateThumbs(pathToDir, profiletype))
            .map { futureResult =>
              // the thumbnails are created
              // return the content of the thumbnail 
              // and since we are in a Future.map this will be a Future[Result]
              Logger.debug(filepath)
              val content = File.getBinaryContent(filepath)
              renderBinary(content, File.getContentType(extention))
            }
        }
        // we could not find the Picture return a NotFound as Future[Result]
        .getOrElse(Future.successful(NotFound("Page not found")))
    }
}

這樣,我們只有一個阻塞線程,而不是兩個,而是創建一個縮略圖,一個正在創建縮略圖,另一個正在等待第一個線程完成創建縮略圖。

在創建縮略圖時,播放可以滿足其他請求,在創建縮略圖之后,播放將以縮略圖進行響應。

暫無
暫無

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

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