aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/scala/async/Async.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/scala/async/Async.scala')
-rw-r--r--src/main/scala/scala/async/Async.scala55
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.
+}