2011-02-11 51 views
4

我必須在我的scala項目中使用java代碼。 java代碼鼓勵使用偵聽器模式。代碼是這樣的:使用java偵聽器模式的Scala語法糖

asyncHttpClient.prepareGet("http://www.ning.com/ ").execute(new AsyncCompletionHandler<Response>(){ 

    @Override 
    public Response onCompleted(Response response) throws Exception{ 
     // Do something with the Response 
     // ... 
     return response; 
    } 

    @Override 
    public void onThrowable(Throwable t){ 
     // Something wrong happened. 
    } 
}); 

我想知道是否有可能使用此代碼在scala中更好地使用。我知道馬丁奧德斯基寫的一篇文章說觀察者模式很糟糕,但我沒有深究這件事。 感謝

回答

3

如果你不能改變你的execute方法的簽名,你可以寫一個方便的方法來簡化創建回調:

def async(f: Response => Response)(handler: Throwable => Unit) = 
    new AsyncCompletionHandler[Response]() { 
     @throws(classOf[Exception]) 
     override def onCompleted(response: Response): Response = 
     f(response) 

     override def onThrowable(t: Throwable) = handler(t) 
    } 

然後你可以寫你的代碼,如

asyncHttpClient.prepareGet("http://www.ning.com/ ").execute(async { 
    response => // do something with response 
} { 
    caught => // handle failure 
} 
2
import scala.actors.Futures.future 
def asyncDiv(n: Int, d: Int) = future { try { Left(n/d) } catch { case ex => Right(ex) } } 

例子:

scala> asyncDiv(5, 2) 
res9: scala.actors.Future[Product with Serializable with Either[Int,java.lang.Throwable]] = <function0> 

scala> res9() 
res10: Product with Serializable with Either[Int,java.lang.Throwable] = Left(2) 

scala> asyncDiv(3, 0) 
res11: scala.actors.Future[Product with Serializable with Either[Int,java.lang.Throwable]] = <function0> 

scala> res11() 
res12: Product with Serializable with Either[Int,java.lang.Throwable] = Right(java.lang.ArithmeticException:/by zero) 
+0

這是全部寫在同一行上的是慣用的scala嗎?或者它只是爲了緊湊,因爲它非常簡短? – 2011-02-11 02:12:59

+0

這似乎很有趣。我會深入討論這個話題。老實說,我不太瞭解左案例類。 – Matroska 2011-02-11 03:07:35