2014-10-14 22 views
13

ReactiveMongo sürücüsünü kullanarak bir Scala uygulaması yazıyorum. Db'ye erişen yöntemler her zaman Future[T] döndürür. Aşağıdaki kod eşdeğerleri mi? (onComplete ile)OnComplete ile Geleceğin flatMap arasındaki fark nedir?

(flatMap ile)

val results: Future[List[Tag]] = Tags.all.toList 
results onComplete { 
    case Success(list) => //do something with list 
    case Failure(t) => //throw the error 
} 

Tags.all.toList.flatMap(list => //do something with list) 

fark nedir?

flatMap, Failure ?? Ve flatMap, onComplete gibi bir geri çağırmadır veya Tags.all.toList bildirimi tamamlanana kadar bekle?

+0

Bu imzasından apaçıktır: Aynı şekilde Monad'ı deneyin, 'flatMap' hatalarla ilgilenmiyor. Monad'ın neyle ilgili olduğu budur: herhangi bir hatayı bozulmadan geçirirsiniz ve işlemlerinizi yalnızca boruda bir hata yoksa uygulayın. Sadece sonunda hata ve başarıları yakalamanız tavsiye edilir –

cevap

27

Şüphe edildiğinde, türleri izleyin.

onComplete döndürür Unit, bu Future sonuçla şeyler yapmak için izin verir, ancak

flatMap listeye bir şey yapmak ve yeni bir Future

dönmek izin bir değer döndürmez Bu yüzden flatMap çok daha güçlüdür, çünkü birden fazla geleceği zincirlemenize, değerlerini bir arada yaparak ve hata durumunu yalnızca en iyi şekilde ele almanıza olanak tanır. Erik Meijer'in sözlerini kullanmak için: "bu seni mutlu yol boyunca yönlendirir".

Yani örneğin bir şey yol boyunca yanlış giderse sen zincir erken bozuldu,

val finalFuture = results 
.flatMap(x => /* do something and return a future */) 
.flatMap(y => /* do something else and return a future */) 
.flatMap(z => /* do something else and return a future */) 
.map(myresult => /* do something */) 

yapabilir ve ilk hata oluştu alırsınız. hatta daha iyi - - zaten olmadığı konusunda bilgi içerir basitçe Future dönmek Eğer başarısızlığı durumunda işlemek gerekiyorsa, artık onComplete kullanabilir veya

val finalFuture = for { 
    x <- results 
    y <- /* do something and return a future */ 
    z <- /* do something and return a future */ 
} yield something(z) 

Bu bile güzel sözdizimi için izin verir async hesaplama başarılı veya değil.

+1

Mükemmel Cevap. Bugün bana yardım etti. –

+1

"Şüphe duyduğunuzda, türleri izleyin." – mulya

+0

'un iyi bir kuralıdır. Bu örnekte, finalFuture bir şey türünden (z) ne olursa olsun bir Gelecek [Nothing] değerini döndürür. Ya bir şeyi (z) geçmeniz gerekiyorsa: T, T'yi bekleyen bir şeye mi? – Azeli

İlgili konular