2014-04-12 3 views
5

प्ले फ्रेमवर्क के iteratee पुस्तकालय एक विधि Enumerator.fromCallback जो तत्व एक भविष्य के परिणामों पर आधारित उत्पन्न करने की अनुमति देता है परिभाषित करता है:scalaz धारा बराबर फ्रेमवर्क के Enumerator.fromCallback खेलने के लिए क्या है

http://www.playframework.com/documentation/2.2.x/Enumerators

def fromCallback[E](
    retriever:() => Future[Option[E]], 
    onComplete:() => Unit =() =>(), 
    onError: (String, Input[E]) => Unit = (_: String, _: Input[E]) =>() 
): Enumerator[E] 

आप यहां एक वेब सेवा से पृष्ठित पृष्ठों को वितरित करने के लिए उपयोग किए जाने का एक अच्छा उदाहरण देख सकते हैं:

http://engineering.klout.com/2013/01/iteratees-in-big-data-at-klout/

def pagingEnumerator(url:String):Enumerator[JsValue]={ 
    var maybeNextUrl = Some(url) //Next url to fetch 
    Enumerator.fromCallback[JsValue] (retriever = { 
    val maybeResponsePromise = 
     maybeNextUrl map { nextUrl=> 
     WS.url(nextUrl).get.map { reponse => 
      val json = response.json 
      maybeNextUrl = (json \ "next_url").asOpt[String] 
      val code = response.status //Potential error handling here 
      json 
     } 
     } 

    /* maybeResponsePromise will be an Option[Promise[JsValue]]. 
    * Need to 'flip' it, to make it a Promise[Option[JsValue]] to 
    * conform to the fromCallback constraints */ 
    maybeResponsePromise match { 
     case Some(responsePromise) => responsePromise map Some.apply 
     case None => PlayPromise pure None 
    } 
    }) 
} 

ऐसा करने के लिए समकक्ष स्केलज़-स्ट्रीम कोड क्या है? मुझे पूरा यकीन है कि इसे Process.emit या Process.await या शायद Process.eval का उपयोग करके किया जा सकता है, लेकिन मुझे एक कार्य-आउट उदाहरण देखना अच्छा लगेगा।

Convert scala 2.10 future to scalaz.concurrent.Future // Task

यह चीजों को आसान बनाता है, तो हम बनाम scalaz टास्क बिट स्केला भविष्य पर ध्यान न दें और मान लेते हैं कि हम एक हो सकता है: यह भी एक scalaz टास्क में स्केला भविष्य उठाने, जिसके लिए यहां एक जवाब नहीं है की आवश्यकता हो सकती टास्क।

+0

एक उदाहरण है रेपो में जो दिखाता है कि कॉलबैक से प्रक्रिया कैसे बनाएं: [CreatingStreams.scala] (https://github.com/scalaz/scalaz-stream/blob/master/src/test/scala/scalaz/stream/examples/ CreatingStreams.scala # L76) –

उत्तर

2

scala.concurrent.Future आप Task.async उपयोग कर सकते हैं से scalaz.concurrent.Task प्राप्त करने के लिए, जब आप अपने हाथ में काम मिल गया है आप इसे इस तरह से कर सकते हैं:

import java.util.concurrent.atomic.AtomicInteger 
    import scalaz.concurrent.Task 
    import scalaz.stream.Process.End 
    import scalaz.stream._ 

    val cnt = new AtomicInteger(0) 

    val task: Task[String] = Task { 
    if (cnt.incrementAndGet() <= 10) s"Task ${cnt.get}" else throw End 
    } 

    Process.repeatEval(task).runLog.run.foreach(println) 
+0

मैंने Task.async चरण जोड़ा, आप यहां पूर्ण उदाहरण देख सकते हैं: https://gist.github.com/ezhulenev/10553038 –

संबंधित मुद्दे