斯卡拉 - 期货没有开始

时间:2018-04-05 19:12:40

标签: scala concurrency

我想在名为YourFilenameHere.jpg的Future方法上启动两个worker。我把它称为我的主要,但似乎承诺永远不会实现,我的主要结束时没有得到任何东西,好像工人没有开始。有任何想法吗?非常感谢。

extraire_phrases

以下是执行后我在控制台中的内容:

object Main {

    val chemin_corpus:String = "src/corpus.txt"
    val chemin_corpus_backup:String = "src/tartarinalpes.txt"
    val chemin_dictionnaire:String = "src/dicorimes.dmp"
    val chemin_dictionnaire_backup:String = "src/dicorimes2.dmp"

    def main(args:Array[String]){

        val quatrain = Promise[List[Phrase]]()

        var grosPoeme = List[Phrase]()

        Future {
          val texte_1 = Phrases.extraire_phrases(chemin_corpus, chemin_dictionnaire)
          val texte_2 = Phrases.extraire_phrases(chemin_corpus_backup, chemin_dictionnaire_backup)

          texte_1.onComplete {
            case Success(list) => {
              val poeme = new DeuxVers(list)
              poeme.ecrire :: grosPoeme
            }
            case Failure(ex) => {
              quatrain.failure(LameExcuse("Error: " + ex.getMessage))
            }
          }

          texte_2.onComplete {
            case Success(lst) => {
              val poeme2 = new DeuxVers(lst)
              poeme2.ecrire :: grosPoeme
            }
            case Failure(ex) => {
              quatrain.failure(LameExcuse("Error: " + ex.getMessage))
            }
          }
        quatrain.success(grosPoeme)
        }

        println(quatrain.future)
        println(grosPoeme)
    }

}

即使我在Future(<not completed>) List() 之前删除了Future {,似乎没有一个正常启动,texte_1会以某种方式启动,有时它会起作用,有时不起作用,而texte_2永远不会启动(永远不会完成)。也没有失败。

//编辑:Alvaro Carrasco的回答是正确的。但是,感谢你们的帮助

2 个答案:

答案 0 :(得分:1)

期货是异步执行的,您的代码不会“等待”它们完成。 onComplete将安排一些代码在未来完成时运行,但不会强制您的程序等待结果。

您需要使用map/flatMap/sequence来处理内部期货,这样您最终会在最后找到一个未来,然后使用Await.result(...)等待它。

这里你真的不需要Promise,因为将来会遇到异常。

这样的事情:

object Main {

  val chemin_corpus:String = "src/corpus.txt"
  ...

  def main(args:Array[String]){
    ...

    val f1 = texte_1
      .map {list => 
        val poeme = new DeuxVers(list)
        poeme.ecrire :: grosPoeme
      }

    val f2 = texte_2
      .map {lst => 
        val poeme2 = new DeuxVers(lst)
        poeme2.ecrire :: grosPoeme
      }

    // combine both futures
    val all = for {
      res1 <- f1
      res2 <- f2
    } yield {
      println(...)
    }
    // wait for the combined future
    Await.result(all, 1.hour)
  }
}

答案 1 :(得分:1)

for-comprehension on Future的解决方案。您需要更改f1f2以执行您需要的操作。 f1f2将并行执行。 for-comprehension提供了优雅的方式来获得未来的结果(它只是flatMapfilter等操作合成的语法糖:

import scala.concurrent.{Await, Future}

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

val f1: Future[Seq[Int]] = Future {
  // Do something here
  Seq(1, 2, 3)
}.recover { case ex =>
    // If Future fails, let's log an exception and return default value
    println(s"Unable to complete f1: $ex")
    Seq.empty[Int]
}

val f2: Future[Seq[Int]] = Future {
  // Do something here
  Seq(4, 5, 6)
}.recover { case ex =>
  // If Future fails, let's log an exception and return default value
  println(s"Unable to complete f2: $ex")
  Seq.empty[Int]
}
// f1 and f2 have started

// we use for-comprehension on Future to get the result
val f = for {
  seq1 <- f1
  seq2 <- f2
} yield seq1 ++ seq2

// Blocking current thread and wait 1 seconds for the result
val r = Await.result(f, 1.seconds)
println(s"Result: $r")