2016-04-12 21 views
30

Şirketimizde Scala'da bazı sistemler geliştiriyoruz ve bazı şüphelerimiz var. Gelecekteki istisnalar eşleştirme hakkında tartışıyorduk ve biz seçeneği 1 veya seçeneğini kullanmalıdır zaman biz bilmiyoruz 2.Scala kurtarma veya kurtarma

val created: Future[...] = ??? 

Seçenek 1:

val a = created recover { 
    case e: database.ADBException => 
    logger.error("Failed ...", e) 
    throw new business.ABusinessException("Failed ...", e) 
} 

Seçenek 2:

val a = created recoverWith { 
    case e: database.ADBException => 
    logger.error("Failed ...", e) 
    Future.failed(new business.ABusinessException("Failed ...", e)) 
} 

Seçenek 1'i veya seçenek 2'yi ne zaman yapmalıyım? Fark nedir?

cevap

46

Aslında sorunun cevabı açıkça scaladocs açıklanmıştır:

/** Creates a new future that will handle any matching throwable that this 
    * future might contain. If there is no match, or if this future contains 
    * a valid result then the new future will contain the same. 
    * 
    * Example: 
    * 
    * {{{ 
    * Future (6/0) recover { case e: ArithmeticException => 0 } // result: 0 
    * Future (6/0) recover { case e: NotFoundException => 0 } // result: exception 
    * Future (6/2) recover { case e: ArithmeticException => 0 } // result: 3 
    * }}} 
    */ 
    def recover[U >: T](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Future[U] = { 

    /** Creates a new future that will handle any matching throwable that this 
    * future might contain by assigning it a value of another future. 
    * 
    * If there is no match, or if this future contains 
    * a valid result then the new future will contain the same result. 
    * 
    * Example: 
    * 
    * {{{ 
    * val f = Future { Int.MaxValue } 
    * Future (6/0) recoverWith { case e: ArithmeticException => f } // result: Int.MaxValue 
    * }}} 
    */ 
    def recoverWith[U >: T](pf: PartialFunction[Throwable, Future[U]])(implicit executor: ExecutionContext): Future[U] = { 

recover tamamladı düz sonuç Future size (map analog) için, recoverWith sonucu (flatMap analog) olarak Future bekler iken.

Zaten Future döndüren bir şeyle kurtarmak Eğer

, aksi recover kullanın recoverWith kullanın:

Yani, burada pratik bir kuraldır. recover sizin için Future daki istisna kaydırılır olarak recover kullanarak durumda

upd , tercih edilir. Aksi takdirde performans artışı ya da herhangi bir şey yoktur, bu yüzden sadece bazı kazanlardan kaçınıyorsunuz.

2

recoverWith'u kullanarak, sarılmış bir geleceğe geri dönmeniz istenir, recover kullanarak bir istisna atmanız istenir. Ben recoverWith kullanmayı tercih

.recoverWith # => Future.failed(t) 
.recover # => throw t 

Ben

Ancak eğer .. fonksiyonel programlama, ben hala tutan düşünüyorum iç kod bloğu olsa bile, bir fonksiyonel tarzda daha az olan durumlar atma daha nesneleri dönen tercih düşünüyorum çünkü Kurtarma bloğundaki dahili bir kod parçacığım var, bu durumda bir istisna atar, bu durumda onu yakalamak ve Future ile paketlemek ya da Denemek, bu kod parçasını sadece recover ile birlikte kullanabilirim ve sizin için istisnai sargıyı ele alır, bu da kodu daha okunaklı ve kompakt hale getirir.

İlgili konular