Skip to content

Instantly share code, notes, and snippets.

@arturaz
Created March 9, 2014 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arturaz/9451460 to your computer and use it in GitHub Desktop.
Save arturaz/9451460 to your computer and use it in GitHub Desktop.
trait MyPromise[A] {
def complete(value: A)
def future: MyFuture[A]
def value: Option[A]
}
trait MyFuture[A] {
def onComplete(f: A => Unit)
def value: Option[A]
def map[B](f: A => B): MyFuture[B]
def flatMap[B](f: A => MyFuture[B]): MyFuture[B]
}
class MyPromiseFuture[A] extends MyPromise[A] with MyFuture[A] {
private[this] var _value = Option.empty[A]
private[this] var listeners = List.empty[A => Unit]
def future = this
def complete(value: A) = {
if (_value.isDefined)
throw new IllegalStateException("Promise is already completed!")
_value = Some(value)
listeners.foreach(_(value))
listeners = List.empty
}
def value = _value
def onComplete(f: A => Unit) = value.fold(listeners ::= f)(f)
def map[B](f: A => B) = {
val p = new MyPromiseFuture[B]
onComplete(f andThen p.complete)
p.future
}
def flatMap[B](f: A => MyFuture[B]) = {
val p = new MyPromiseFuture[B]
onComplete(a => f(a).onComplete(p.complete))
p.future
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment