From 62f012c2bbd948a1922a9eafb13267dc45f8392c Mon Sep 17 00:00:00 2001 From: aleksandar Date: Fri, 27 Jan 2012 11:31:43 +0100 Subject: Implement the ensure and andThen methods on futures. --- src/library/scala/concurrent/Future.scala | 57 ++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'src/library') diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala index 29b17cf70a..1b20c91e49 100644 --- a/src/library/scala/concurrent/Future.scala +++ b/src/library/scala/concurrent/Future.scala @@ -155,7 +155,7 @@ self => val p = newPromise[Throwable] - this onComplete { + onComplete { case Left(t) => p success t case Right(v) => p failure noSuchElem(v) } @@ -377,6 +377,61 @@ self => p.future } + /** Applies the side-effecting function to the result of this future, and returns + * a new future with the result of this future. + * + * This method allows one to enforce that the callbacks are executed in a + * specified order. + * + * Note that if one of the chained `andThen` callbacks throws + * an exception, that exception is not propagated to the subsequent `andThen` + * callbacks. Instead, the subsequent `andThen` callbacks are given the original + * value of this future. + * + * The following example prints out `5`: + * + * {{{ + * val f = future { 5 } + * f andThen { + * case r => sys.error("runtime exception") + * } andThen { + * case Left(t) => println(t) + * case Right(v) => println(v) + * } + * }}} + */ + def andThen[U](pf: PartialFunction[Either[Throwable, T], U]): Future[T] = { + val p = newPromise[T] + + onComplete { + case r => + try if (pf isDefinedAt r) pf(r) + finally p complete r + } + + p.future + } + + /** Executes a piece of code once this future is completed, regardless of whether + * or not the future fails or succeeds, and returns a new future with the result of this + * future. + * + * This method allows one to enforce ordering. + * + * The below example always executes the `println` calls in order: + * {{{ + * val f = future { 5 } + * f ensure { + * println("The value is available.") + * } ensure { + * println("The application can now end.") + * } + * }}} + */ + def ensure[U](body: =>U): Future[T] = andThen { + case _ => body + } + /** Creates a new future which holds the result of either this future or `that` future, depending on * which future was completed first. * -- cgit v1.2.3