Later
Introduction
Heavily inspired by javascript promises, Later(s) are mainly here to ease the bridge between kotlin coroutines for multiplatform and their respective platforms.
Problem Statement
While it is true that kotlin can compile down to (js,jvm or native). Usually there are some limitations. One of the heaviest ones are usually trying to call suspend functions from other platforms (mostly Java and Javascript).
A Later, comes in handy as it lets you work with suspend functions from kotlin, promises from javascript and also Futures from Java. All you have to do is return a Later object and you are good to go.
Samples
In Kotlin you can do something like this
class TokenService(val scope: CoroutineScope) {
fun getToken(id: String) = scope.later { // this is a suspending labda
delay(100) // simulating heavy work
getUserTokenFromServer() // returned result will be the valued that will be Later delivered to you upon completion
}
}
Notice that getToken doesn't have to be a suspend function. Which means, it is callable from Java and Javascript. Even C
In Javascript, a Later is a Thenable
meaning you can chain then
, catch
and finally methods as you would
const tokenService = require('your-published-shared-lib');
tokenService.getUser("user-1")
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.catch(failureCallback)
.finally(finalState => {
console.log(`Got the final result: ${finalState}`);
});
But since a Thenable is never really fully a Promise, We have provided a way that you can easily convert a Later to a Promise like so
const tokenService = require('your-published-shared-lib');
tokenService.getUser("user-1").asPromise() // notice asPromise() here
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.catch(failureCallback)
.then(finalResult => {
console.log(`Got the final result: ${finalResult}`);
});
Using the same kotlin code in java, is piece of cake
import your.published.shared.lib.TokenService;
class Test {
TokenService tokenService = TokenService.getDefault();
public static void testLater() {
tokenService.getToken("user-1")
.then(result -> doSomethingElse(result))
.then(newResult -> doThirdThing(newResult))
.error(failureCallback) // notice it is error instead of catch (catch is a reserved keyword in java)
.complete(finalState -> {
console.log("Got the final result: " + finalState);
return null;
});
}
}
as normal, if you are well versed to using CompletableFutures and like that, there is a convenient method asCompletableFuture()
that returns a CompletableFuture backed by the Later
Setup
dependencies {
implementation("tz.co.asoft:later-core:0.0.40")
implementation("tz.co.asoft:later-ktx:0.0.40") // if using with kotlinx coroutines
}
Extensions
Later is being made to extend into any Deferred data type. It even has built in integration with Deferred support from kotlinx coroutines
Conclusion
Now, go and build real multiplatform code, that can be shared across mobile (android only for now), web and server (jvm or node)
Coming soon
ios/macos support