2015-06-30 18 views
5

Promises koleksiyonum var. Ortaya çıkan Futures'u oluşturmak için etkili bir yol arıyordum. Şu ben onları birleştirmek için bulduğumuz en temiz yolu şöyle bir scalaz Monoid kullanmaktı: scalaz gerektirmediğini Bunu yapmak için temiz bir yolu"Futures" in bir listesini nasıl oluştururum?

val promises = List(Promise[Unit], Promise[Unit], Promise[Unit]) 

    promises.map(_.future).reduce(_ |+| _).onSuccess { 
    case a => println(a) 
    } 

    promises.foreach(_.success(())) 

var mı? Koleksiyondaki Futures sayısı, koleksiyonda değişecektir ve çok sayıda ara koleksiyon arzu edilmeyecektir.

+0

"Promises" yerine "Futures" öğesini toplamanızı ister misiniz? –

+0

Burada yapmakta olduğum şey, .map() –

cevap

7

Sen Future.traverse kullanabilirsiniz:

import scala.concurrent.ExecutionContext.Implicits.global 
import scala.concurrent.{ Future, Promise } 

val promises = List(Promise[Unit], Promise[Unit], Promise[Unit]) 
Future.traverse(promises)(_.future) 

Bu size de biliyorum "ara koleksiyonları sürü" olarak nitelemek değil, ama ille ideal değildir gelmez bir Future[List[Unit]], verecektir. Future.reduce da çalışır:

Future.reduce(promises.map(_.future))((_, _) =>()) 

Bu future hiç memnun olduğunda memnun olacak bir Future[Unit] döndürür.

+0

Bir koleksiyon oluşturduğu düşünülürse, monoid daha verimli olup olmadığını merak ediyorum. Ama teşekkürler, bu tam olarak aradığım şeydi - görünüşe göre Gelecek Nesnesi sürümüne hiç tıklanmadığım için API belgelerini nasıl kullanacağımı bilmiyorum. –

+0

'küçültme 'bir koleksiyon oluşturmuyor, bu nedenle en azından monoid kadar verimli olmalı (muhtemelen daha fazla). –

+0

Evet, yukarıdaki örnekte küçültmeyi kullanıyorum, daha hızlı olsun ya da olmasın; Traverse bir liste oluşturur, bu yüzden küçük bir yük getirebilir düşünüyorum. Sadece bir sürü futures var, bu yüzden liste kısa ve muhtemelen önemli değil. –

3

Future.sequence9, istediğiniz yöntemdir.

+0

'Future.traverse 'ile gelecekleri ayıklamak muhtemelen biraz daha mantıklı (cevaba bakın), ama yine de en az bir gereksiz ara koleksiyon yaratıyor. –

+0

Sıra, traversi basitleştirir, böylece ikiniz de haklısınız ama sadece birini kabul edebilirim. Afedersiniz. –

+0

Bu durumda "traverse" aslında hem daha basit hem de daha verimli - gerekli "map" ve "sequence" i tek bir işlemle birleştirir. –

İlgili konular