9

私は Scala で初めて Futures を使用する作業を行っており、flatMap コンビネータの使用例に取り組んでいます。私はこの議論をフォローしてきました:

http://docs.scala-lang.org/overviews/core/futures.html

具体的には、この例:

val usdQuote = future { connection.getCurrentValue(USD) }
val chfQuote = future { connection.getCurrentValue(CHF) }
val purchase = for {
    usd <- usdQuote
    chf <- chfQuote
      if isProfitable(usd, chf)
} yield connection.buy(amount, chf)

purchase onSuccess {
    case _ => println("Purchased " + amount + " CHF")
}

これに翻訳されます:

val purchase = usdQuote flatMap {
    usd =>
         chfQuote
        .withFilter(chf => isProfitable(usd, chf))
        .map(chf => connection.buy(amount, chf))
}

私が把握するのに少し苦労しているのは、これがいつどのように flatMap を実行するかです。

usdQuote と chfQuote は「ある時点」で「あるスレッド」によって実行され、登録されたコールバック関数が呼び出されることを理解しています。質問は次のとおりです。

a) usdQuote と chfQuote は同時に実行されますか? (私は彼らがそうであると確信しています)。

b) flatMap は Future useQuote の値を usd にどのように割り当てますか? 同様に、操作 usdQuote が完了すると呼び出されますか?

c) 'flatMap' および 'map' 操作を実行しているスレッドはどれですか (おそらく、最後の質問の続きです)。

乾杯。

4

3 に答える 3

10
  • a)それらを作成したとき、スコープ内の暗黙のExecutionContextに対して実行を開始しているため、実行方法によっては同時に実行される可能性があります。

  • b)実際には値自体を割り当てませんが、実装はonCompleteメソッドを使用して、結果に到達すると、渡した関数をトリガーします。現時点では、これは私が参照しているそのflatMapメソッドにリンクしているはずです:https ://github.com/scala/scala/blob/v2.11.2/src/library/scala/concurrent/Future.scala#L246

  • c)前述のExecutionContextを介して実行されている場合、これらのFutureインスタンスが異なるExecutionContextで実行できる場合は、for-comprehensionの一部が異なるスレッドプールで実行される可能性があることも考慮してください。

于 2013-01-18T08:16:17.537 に答える
2

Arun Manivannanの「 Scala notes – Futures – 3 (Combinators and Async)」 にも同時Future実行の良い例があります。

Futures並行して実行する必要があります。
これを実現するには、Futureブロックを抽出して個別に宣言するだけです。

コード:

val oneFuture: Future[Int] = Future {
  Thread.sleep(1000)
  1
}

val twoFuture: Future[Int] = Future {
  Thread.sleep(2000)
  2
}

val threeFuture: Future[Int] = Future {
  Thread.sleep(3000)
  3
}

for-comprehension :

def sumOfThreeNumbersParallelMapForComprehension(): Future[Int] = for {  
    oneValue <- oneFuture
    twoValue <- twoFuture
    threeValue <- threeFuture
} yield oneValue + twoValue + threeValue

フラットマップ:

def sumOfThreeNumbersParallelMap(): Future[Int] = oneFuture.flatMap { oneValue =>  
    twoFuture.flatMap { twoValue =>
      threeFuture.map { threeValue =>
        oneValue + twoValue + threeValue
      }
    }
}

テスト:

describe("Futures that are executed in parallel") {
  it("could be composed using for comprehensions") {
    val futureCombinators = new FutureCombinators
    val result = timed(Await.result(futureCombinators.sumOfThreeNumbersParallel(), 4 seconds))
      result shouldBe 6
  }
}

それは次のことを示しています。

  1. Futureあるタイプの値のコンテナです (つまり、タイプを引数として受け入れ、それなしでは存在できません)。またはまたはを使用でき
    ます。単純な だけを使用することはできません。 これの凝った用語はtype-constructorです。 比較すると、 aは型コンストラクタ (およびモナド) です。 Aは、型またはその他の型の値のコンテナーです。含まれる型のない/は存在しません。Future[Int]Future[String]Future[AwesomeClass]Future

    List
    ListInt, StringListFuture
  2. FuturehasflatMapおよびunitfunctions (結果としてmap関数も)。
于 2016-06-14T19:00:36.073 に答える