स्कैला के भविष्य के असंगत व्यवहार के साथ परेशानी हो रही है

मुझे स्कैला के भविष्य के असंगत व्यवहार के साथ एक छोटी सी समस्या का सामना करना पड़ रहा है। नीचे कोड है जो मैं कर रहा हूँ

package TryFuture

import scala.concurrent.Future
import scala.concurrent.future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.util.Random

class FutureCappuccino {
 //Some type aliases, just for getting more meaningful method signatures:
  type CoffeeBeans = String
  type GroundCoffee = String
  case class Water(temperature: Int)
  type Milk = String
  type FrothedMilk = String
  type Espresso = String
  type Cappuccino = String

 //some exceptions for things that might go wrong in the individual steps
 //(we'll need some of them later, use the others when experimenting
 //with the code):
  case class GrindingException(msg: String) extends Exception(msg)
  case class FrothingException(msg: String) extends Exception(msg)
  case class WaterBoilingException(msg: String) extends Exception(msg)
  case class BrewingException(msg: String) extends Exception(msg)

  def grind(beans: CoffeeBeans): Future[GroundCoffee] = future {
    println("Start grinding with thread: " + Thread.currentThread().getId())
    //Thread.sleep(10)
    if (beans == "baked beans") throw GrindingException("are you joking?")
    println("Finished grinding..")
    s"ground coffee of $beans"
  }

  def heatWater(water: Water): Future[Water] = future {
    println("Heating the water with thread: " + Thread.currentThread().getId())
    //Thread.sleep(10)
    println("It's hot!!")
    water.copy(temperature = 85)
  }

  def frothMilk(milk: Milk): Future[FrothedMilk] = future {
    println("milk frothing system engaged! with thread: " + Thread.currentThread().getId())
    //Thread.sleep(Random.nextInt(10))
    println("shutting down milk frothing system")
    s"frothed $milk"
  }

  def brew(coffee: GroundCoffee, heatedWater: Water): Future[Espresso] = future {
    println("happy brewing :) with thread: " + Thread.currentThread().getId())
    //Thread.sleep(Random.nextInt(10))
    println("it's brewed!")
    s"espresso"
  }

  def combine(espresso: Espresso, frothedMilk: FrothedMilk): Future[String] = future {
    println("Combine starting with thread: " + Thread.currentThread().getId())
    "Your Cappuccino is ready"
  }

 //going through these steps sequentially:
  def prepareCappuccino() = {
    val brewed = for {
      coffee <- grind("not baked beans")
      water <- heatWater(Water(25))
      brewed <- brew(coffee, water)
    } yield brewed

    brewed
  }

}

अब मैं जो उम्मीद कर रहा हूं वह यह है कि पानी खत्म होने के लिए इंतजार करेगा और फिर ब्रू पीसने के लिए इंतजार करेगा और गर्मी खत्म हो जाएगी। लेकिन जब मैं अपने मैकबुक में इस प्रोग्राम को चला रहा हूं, तो मुझे केवल नीचे ओ/पी मिल रहा है धागे के साथ पीसना शुरू करें: 8 और फिर निष्पादन पूरा हो जाता है। यह बाकी सामानों की प्रतीक्षा नहीं कर रहा है। यह पता लगाने में सक्षम नहीं है कि मैं यहां क्या खो रहा हूं और यह क्यों इंतजार नहीं कर रहा है? कोई मदद?

0

2 उत्तर

आखिरकार अवधारणा को नीचे दिए गए परिवर्तनों के साथ स्पष्ट किया गया:

package TryFuture

import scala.concurrent.Future
import scala.concurrent.future
import scala.util.{Success,Failure}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.util.Random

class FutureCappuccino {
 //Some type aliases, just for getting more meaningful method signatures:
  type CoffeeBeans = String
  type GroundCoffee = String
  case class Water(temperature: Int)
  type Milk = String
  type FrothedMilk = String
  type Espresso = String
  type Cappuccino = String

 //some exceptions for things that might go wrong in the individual steps
 //(we'll need some of them later, use the others when experimenting
 //with the code):
  case class GrindingException(msg: String) extends Exception(msg)
  case class FrothingException(msg: String) extends Exception(msg)
  case class WaterBoilingException(msg: String) extends Exception(msg)
  case class BrewingException(msg: String) extends Exception(msg)

  def grind(beans: CoffeeBeans): Future[GroundCoffee] = {
    println("Start grinding with thread: " + Thread.currentThread().getId())
    Thread.sleep(200)
    if (beans == "baked beans") throw GrindingException("are you joking?")
    future {
      Thread.sleep(200)
      s"ground coffee of $beans"
    }
  }

  def heatWater(water: Water): Future[Water] = {
    println("Heating the water with thread: " + Thread.currentThread().getId())
    Thread.sleep(200)
    future {
      water.copy(temperature = 85)
    }
  }

  def frothMilk(milk: Milk): Future[FrothedMilk] = {
    println("milk frothing system engaged! with thread: " + Thread.currentThread().getId())
    Thread.sleep(200)
    future {
      s"frothed $milk"
    }
  }

  def brew(coffee: GroundCoffee, heatedWater: Water): Future[Espresso] = {
    println("happy brewing :) with thread: " + Thread.currentThread().getId())
    Thread.sleep(200)
    future {
      s"espresso"
    }
  }

  def combine(espresso: Espresso, frothedMilk: FrothedMilk): Future[String] =  {
    println("Combine starting with thread: " + Thread.currentThread().getId())
    Thread.sleep(200)
    future {
      Thread.sleep(20)
      "Your Cappuccino is ready"
    }
  }

 //going through these steps sequentially:
  def prepareCappuccino() = {
    val coffees = grind("not baked beans")
    val waters = heatWater(Water(25))
    val milks = frothMilk("milk")

    val combined = for {
      coffee <- coffees
      water <- waters
      brewed <- brew(coffee, water)
      milk <- milks
      combined <- combine(brewed, milk)
    } yield combined

    combined onComplete {
      case Success(t)   => println("combined is done")
      case Failure(t)   => t
    }

    coffees onComplete {
      case Success(t)   => println("Coffee is done")
      case Failure(t)   => t
    }

    combined

  }

}

And finally ====>

val myFutureCappuccino = new FutureCappuccino()
  val myCoffee = myFutureCappuccino.prepareCappuccino
  Thread.sleep(2000)
  myCoffee onComplete{
    case Success(t) =>  println(t)
    case Failure(p) =>  println(p.getMessage())
  }

आउटपुट के साथ अब खुश

Start grinding with thread: 1
Heating the water with thread: 1
milk frothing system engaged! with thread: 1
happy brewing :) with thread: 8
Coffee is done
Combine starting with thread: 8
combined is done
Your Cappuccino is ready

यहां जवाब साझा करना उम्मीद है कि यह किसी की मदद कर सकता है। धन्यवाद।

0
जोड़ा
क्या आप उत्तर के मुख्य पहलू को समझा सकते हैं जिसने इसे काम किया है?
जोड़ा लेखक Jus12, स्रोत
def grind(beans: CoffeeBeans): Future[GroundCoffee] = future {
    println("Start grinding with thread: " + Thread.currentThread().getId())

    if (beans == "baked beans") throw GrindingException("are you joking?")

    ...
}

def prepareCappuccino() = {
  val brewed = for {
    coffee <- grind("baked beans")
    water <- heatWater(Water(25))
    brewed <- brew(coffee, water)
  } yield brewed

  brewed
}

grind विधि अपवाद फेंक रहा है, जिससे अभिव्यक्ति के परिणामस्वरूप विफल हुआ भविष्य।

जब पीस पारित किया जाता है "बेक्ड बीन्स नहीं", यह अपेक्षा के अनुसार काम करता है।

आपका मुख्य धागा बहुत जल्द छोड़ रहा है।

Thread.sleep या Await.result का प्रयोग करें

0
जोड़ा
हाँ इसके लिए खेद है। अब भी धागे के साथ पीसने शुरू करें: 8 पीसने समाप्त .. कंसोल में आ रहे हैं। गर्मी वाटर नहीं आ रहा है ..
जोड़ा लेखक Sudipta Deb, स्रोत
हाँ यह सच है। लेकिन यही वह जवाब है जिसे मैं देख रहा हूं। यह इंतजार क्यों नहीं कर रहा है? क्या यह कुछ है जो मैं यहाँ याद कर रहा हूँ?
जोड़ा लेखक Sudipta Deb, स्रोत
आपका मुख्य धागा ऐसा लगता है कि ऐसा लगता है कि पर्याप्त नहीं है।
जोड़ा लेखक Shyamendra Solanki, स्रोत
चूंकि वायदा असीमित रूप से काम करते हैं, इसलिए उनके पूरा होने में मनमाना विलंब हो सकता है। ध्यान दें कि विधि तैयार करना भविष्य को वापस कर रहा है।
जोड़ा लेखक Shyamendra Solanki, स्रोत