2013-12-18 71 views
1

我有一個用scala編寫的基於actor的應用程序(使用)。現在我有一個演員,應該按照預定義順序發送各種HTTP請求,以便在網絡中配置設備。動作順序清潔代碼

我把所有的HTTP東西封裝在一個單獨的類中供我的演員訪問。 每個配置步驟當然可能會失敗,因此我使用Try[Int]作爲處理與設備通信的方法(返回HTTP響應代碼作爲Try的內容)的返回類型。

現在我的問題是,每個配置步驟取決於所有步驟之前,已成功完成,因此我的代碼變得難以閱讀(在我的oppinion)。

我把它實現基本上是這樣的

action1 match { 
    case Failure(err) => //report error 
    case Success(retCode) if retCode < 400 => 
    nextStep match { 
     ... 
    } 
} 

經過幾個動作這只是成爲一個巨大的聲明,你cannont第一眼看到是怎麼回事。

那麼我該如何去寫一個乾淨的代碼 - 時尚?

回答

1

您可以實現您的行爲作爲...的動作順序序列:

阻塞版本:

def seq: Seq[() => Try[Int]] = ??? 

// find first failure 
def failed: Option[Try[Int]] = seq.view.map{ _() }.find { 
    case Failure(err) => 
     //report error 
     true 
    case Success(retCode) => retCode > 400 
    } 

對於非阻塞版本,你應該使用Future而不是Try

val seq: List[() => Future[Int]] = ??? 

def isSuccess(actions: List[() => Future[Int]]): Future[Boolean] = actions match { 
    case h :: tail => h().flatMap { c => 
     if (c > 400) Future(false) 
     else isSuccess(tail) 
    } 
    case Nil => Future(true) 
} 
+0

啊,如果'find'有''true',就會停止執行。事後看來,這是一個明顯的解決方案^^ – mgttlinger

+0

如果它在這裏封鎖並不重要,因爲這個演員的整個目的是要執行這些動作,而且他們必須相互等待。 – mgttlinger

+0

@mgttlinger:我沒有知道如何獲得'HTTP'響應,但是如果庫提供'Future [Response]',你不應該使用'Await'將它轉換爲'Try'。 – senia