Skip to content

Lightweight asynchronous values for Kotlin. Serves the same purpose as Future, Deferred, Promise. Great for procrastinators

License

Notifications You must be signed in to change notification settings

rtmigo/later_kt

Repository files navigation

Generic badge Generic badge

A Later represents a potential value, that will be available at some time in the future.

  • .value returns the value, or throws if the value is not set yet

  • .isComplete returns true, if the value is set

  • .await() waits until the value is set

The object does not provide concurrency or task queuing. It just fires callbacks as lightly as possible while being thread safe.

  • .onComplete, .onSuccess, .onError set callbacks to be run when Later is completed (or run the callbacks immediately, if Later is already completed)

  • .map maps the value to other Later value

The object is somewhat similar to Deferred, Future and Promise.

Install

settings.gradle.kts

sourceControl {
    gitRepository(java.net.URI("https://github.com/rtmigo/later_kt.git")) {
        producesModule("io.github.rtmigo:later")
    }
}

build.gradle.kts

dependencies {
    implementation("io.github.rtmigo:later") {
        version { branch = "staging" }
    }
}

Basic example

import io.github.rtmigo.later.*

fun slowComputation(x: Int): Later<Int> {
    val result = Later.completable<Int>()
    thread {
        // one second later assign value to the returned object
        sleep(1000)
        result.value = x * 2   
    }
    return result  // return immediately
}

fun main() {
    // print "16" after one second
    println(slowComputation(8).await()) 
}

Creating a Later

Later.completable<T>() creates an object without .value. The value must be assigned before it can be read.

val a = Later.completable<Int>()
assert(a.isComplete == false)

a.value = 5

assert(a.isComplete == true)
assert(a.value == 5)

By calling Later.value(v) or v.asLater() we create an immutable Later, with v as value.

val c = Later.value(7)

assert(c.isComplete == true)
assert(c.value == 7)

Async callbacks

// init
val a = Later.completable<String>()
a.onSuccess { println("What is $it?!") }

// assigning the value will trigger the callback
a.value = "love"

// What is love?!

We can set multiple callbacks for the same Later.

val a = Later.completable<String>()
a.onSuccess { println("What is $it?!") }
a.onSuccess { println("Is $it great?!") }
a.value = "Britain"

// What is Britain?
// Is Britain great? 

When value is already set, callbacks are run immediately.

val iam = Later.value("Groot")

a.onSuccess { println("You are $it") }

// You are Groot

We can use Unit as value if all we need is a callback.

val kindaEvent = mutableLater<Unit>()
kindaEvent.onSuccess { println("Kinda callback") }

kindaEvent.value = Unit

// Kinda callback

Mapping

We can specify later transformations for a later value.

map method receives the previous value and returns a new Later.

val a = Later.completable<Int>()                  // a is CompletableLater<Int>
val b = a.map { "The number is $it".asLater() }   // b is Later<String>
val c = b.map { (it.uppercase()+"!").asLater() }  // c is Later<String>

// None of the objects have a value yet. Attempting to read `.value` 
// will throw an exception. But we can assign value to `a`:

a.value = 5

println(a.value)  // 5
println(b.value)  // The number is 5
println(c.value)  // THE NUMBER IS 5!

License

Copyright © 2022 Artyom IG <github.com/rtmigo>

Licensed under the MIT License

About

Lightweight asynchronous values for Kotlin. Serves the same purpose as Future, Deferred, Promise. Great for procrastinators

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published