Skip to content

Instantly share code, notes, and snippets.

@exallium
Created February 14, 2019 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save exallium/c38217193e35852c9b0981fc60113f7c to your computer and use it in GitHub Desktop.
Save exallium/c38217193e35852c9b0981fc60113f7c to your computer and use it in GitHub Desktop.
Quick and dirty Promise in Kotlin
sealed class Either<out L, out R> {
data class Left<out L>(val l: L) : Either<L, Nothing>()
data class Right<out R>(val r: R) : Either<Nothing, R>()
}
fun asdf() {
val p = Promise<Int> { resolve, reject ->
resolve(Either.Left(4))
}
p.then { Either.Left(4) }.catch { error("Something bad happened!") }
}
class Promise<T>(fn: ((Either<T, Promise<T>>) -> Unit, (Throwable) -> Unit) -> Unit) {
private enum class State {
WAITING_FOR_DATA,
ERROR,
SUCCESS
}
private var state: State = State.WAITING_FOR_DATA
private lateinit var data: Either<T, Promise<T>>
private lateinit var error: Throwable
private val dataCallbackSet: MutableSet<() -> Unit> = mutableSetOf()
private val catchCalbackSet: MutableSet<() -> Unit> = mutableSetOf()
init { fn(this::resolve, this::reject) }
fun <R> then(fn: (t: Either<T, Promise<T>>) -> Either<R, Promise<R>>): Promise<R> {
return Promise { resolve, reject ->
fun registerCallbacks() {
dataCallbackSet.add {
resolve(fn(data))
}
catchCalbackSet.add {
reject(error)
}
}
when (state) {
State.WAITING_FOR_DATA -> registerCallbacks()
State.SUCCESS -> resolve(fn(data))
State.ERROR -> reject(error)
}
}
}
fun catch(fn: (e: Throwable) -> Unit): Promise<T> {
when (state) {
State.WAITING_FOR_DATA -> catchCalbackSet.add { fn(error) }
State.ERROR -> fn(error)
State.SUCCESS -> {}
}
return this
}
private fun resolve(data: Either<T, Promise<T>>) {
this.data = data
this.state = State.SUCCESS
dataCallbackSet.forEach { it() }
}
private fun reject(error: Throwable) {
this.error = error
this.state = State.ERROR
catchCalbackSet.forEach { it() }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment