Ответ 1
Я не могу предоставить ссылку на документацию, в которой будет четко указано, что действительно произойдет, но мы можем провести простой эксперимент, который ответит на ваш вопрос.
Просто откройте Scala REPL и вставьте следующий код:
import java.util.concurrent.Executors
import scala.concurrent._
implicit val ec = new ExecutionContext {
val threadPool = Executors.newFixedThreadPool(1000);
def execute(runnable: Runnable) {
threadPool.submit(runnable)
println("execute!")
}
def reportFailure(t: Throwable) {}
}
future { 1 } map(_ + 1) filter (_ > 0) map (_ + 2)
Он будет печатать:
scala > future {1} map (_ + 1) фильтр (_ > 0) map (_ + 2)
выполнить!
выполнить!
выполнить!
выполнить!
res0: scala.concurrent.Future [Int] = scala.concurrent.impl.Promise $DefaultPromise @7ef3de76
Так выполняется вызов для каждой отдельной операции, которую вы выполняете (и, как вы можете проверить документацию, каждая функция, такая как карта или фильтр, принимает ExecutionContext как неявный параметр: http://www.scala-lang.org/api/2.10.6/#scala.concurrent.Future)
Если вы ищете альтернативную структуру, вы должны проверить фразу "Scalaз". У меня нет опыта с ними, но они кажутся тем, что вы ищете. Проверьте эту тему: https://groups.google.com/forum/#!msg/scalaz/-PuakIf-g_4/7ydrU5VIfDQJ
В отличие от реализации
Future
в Scala 2.10,map
иflatMap
НЕ запускают новые задачи и не требуют неявногоExecutionContext
. Вместо этогоmap
иflatMap
просто добавляют к текущему (трассируемому) продолжению, которое будет выполняться потоком "current", если явно не разветвлено черезFuture.fork
илиFuture.apply
. Это означает, чтоFuture
обеспечивает гораздо лучшее повторное использование потоков, чем реализация 2.10, и избегает ненужных циклов представления пула потоков.
Future
также отличается от типа Scala 2.10Future
тем, что он не обязательно представляет собой текущее вычисление. Вместо этого мы снова вводим недетерминизм с использованием функций интерфейсаscalaz.Nondeterminsm
. Это упрощает нашу реализацию и упрощает анализ кода, поскольку порядок эффектов и точки недетерминированности становятся полностью явными и не зависят от порядка оценки Scala.ВАЖНОЕ ЗАМЕЧАНИЕ:
Future
не включает обработку ошибок и обычно используется только как строительный блок для библиотек, которые хотят использовать возможностиFuture
, но хотят разработать собственную стратегию обработки ошибок. См.scalaz.concurrent.Task
для типа, который расширяетFuture
с правильной обработкой ошибок - это всего лишь оболочка дляFuture[Either[Throwable,A]]
с рядом дополнительных функций удобства.