diff options
Diffstat (limited to 'src/main/scala/scala/async/Async.scala')
-rw-r--r-- | src/main/scala/scala/async/Async.scala | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/main/scala/scala/async/Async.scala b/src/main/scala/scala/async/Async.scala new file mode 100644 index 0000000..c45a9c6 --- /dev/null +++ b/src/main/scala/scala/async/Async.scala @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com> + */ + +package scala.async + +import scala.language.experimental.macros +import scala.concurrent.{Future, ExecutionContext} +import scala.reflect.internal.annotations.compileTimeOnly + +/** + * Async blocks provide a direct means to work with [[scala.concurrent.Future]]. + * + * For example, to use an API to that fetches as web page to fetch + * two pages and add their lengths: + * + * {{{ + * import ExecutionContext.Implicits.global + * import scala.async.Async.{async, await} + * + * def fetchURL(url: URL): Future[String] = ... + * + * val sumLengths: Future[Int] = async { + * val body1 = fetchURL("http://scala-lang.org") + * val body2 = fetchURL("http://docs.scala-lang.org") + * await(body1).length + await(body2).length + * } + * }}} + * + * Note that the in the following program, the second fetch does *not* start + * until after the first. If you need to start tasks in parallel, you must do + * so before `await`-ing a result. + * + * {{{ + * val sumLengths: Future[Int] = async { + * await(fetchURL("http://scala-lang.org")).length + await(fetchURL("http://docs.scala-lang.org")).length + * } + * }}} + */ +object Async { + /** + * Run the block of code `body` asynchronously. `body` may contain calls to `await` when the results of + * a `Future` are needed; this is translated into non-blocking code. + */ + def async[T](body: T)(implicit execContext: ExecutionContext): Future[T] = macro internal.ScalaConcurrentAsync.asyncImpl[T] + + /** + * Non-blocking await the on result of `awaitable`. This may only be used directly within an enclosing `await` block. + * + * Internally, this will register the remainder of the code in enclosing `async` block as a callback + * in the `onComplete` handler of `awaitable`, and will *not* block a thread. + */ + @compileTimeOnly("`await` must be enclosed in an `async` block") + def await[T](awaitable: Future[T]): T = ??? // No implementation here, as calls to this are translated to `onComplete` by the macro. +} |