Kotlin Standard Library for experimental WebAssembly JS platform providing core functionality and JavaScript interoperability
—
JavaScript Promise integration with full async/await support and error handling for asynchronous operations in Kotlin/Wasm.
JavaScript Promise object with comprehensive support for asynchronous operations.
/**
* JavaScript Promise object for asynchronous operations
* @param T Type of the resolved value (must extend JsAny?)
* @param executor Function that receives resolve and reject callbacks
*/
external class Promise<out T : JsAny?>(
executor: (resolve: (T) -> Unit, reject: (JsAny) -> Unit) -> Unit
) : JsAnyChain operations and handle promise results with standard JavaScript Promise methods.
/**
* Register fulfillment handler for the promise
* @param onFulfilled Callback for successful resolution
* @return Promise<S> New promise with transformed result
*/
fun <S : JsAny?> Promise<T>.then(onFulfilled: ((T) -> S)?): Promise<S>
/**
* Register fulfillment and rejection handlers for the promise
* @param onFulfilled Callback for successful resolution
* @param onRejected Callback for rejection
* @return Promise<S> New promise with transformed result
*/
fun <S : JsAny?> Promise<T>.then(
onFulfilled: ((T) -> S)?,
onRejected: ((JsAny) -> S)?
): Promise<S>
/**
* Register rejection handler for the promise
* @param onRejected Callback for handling rejection
* @return Promise<S> New promise with handled result
*/
fun <S : JsAny?> Promise<T>.catch(onRejected: (JsAny) -> S): Promise<S>
/**
* Register cleanup handler that runs regardless of promise outcome
* @param onFinally Callback for cleanup operations
* @return Promise<T> Promise with same result but with cleanup
*/
fun Promise<T>.finally(onFinally: () -> Unit): Promise<T>Static methods for creating and combining promises.
/**
* Wait for all promises to resolve
* @param promise Array of promises to wait for
* @return Promise<JsArray<out S>> Promise resolving to array of results
*/
fun <S : JsAny?> Promise.Companion.all(
promise: JsArray<out Promise<S>>
): Promise<JsArray<out S>>
/**
* Wait for first promise to resolve or reject
* @param promise Array of promises to race
* @return Promise<S> Promise resolving to first completed result
*/
fun <S : JsAny?> Promise.Companion.race(
promise: JsArray<out Promise<S>>
): Promise<S>
/**
* Create rejected promise with given reason
* @param e Rejection reason
* @return Promise<Nothing> Rejected promise
*/
fun Promise.Companion.reject(e: JsAny): Promise<Nothing>
/**
* Create resolved promise with given value
* @param e Value to resolve with
* @return Promise<S> Resolved promise
*/
fun <S : JsAny?> Promise.Companion.resolve(e: S): Promise<S>
/**
* Create resolved promise from another promise
* @param e Promise to resolve with
* @return Promise<S> Promise with same resolution
*/
fun <S : JsAny?> Promise.Companion.resolve(e: Promise<S>): Promise<S>
/**
* Create resolved promise with no value (void)
* @return Promise<Unit> Resolved promise with unit value
*/
fun Promise.Companion.resolve(): Promise<Unit>Usage Examples:
import kotlin.js.*
// Create a simple promise
val promise = Promise<JsString> { resolve, reject ->
val success = true // Some condition
if (success) {
resolve("Operation successful!".toJsString())
} else {
reject("Operation failed".toJsString())
}
}
// Handle the promise
promise
.then { result ->
println("Success: $result")
result
}
.catch { error ->
println("Error: $error")
"default".toJsString()
}
.finally {
println("Cleanup operations")
}// Simulating an API call
fun fetchUserData(userId: String): Promise<JsString> {
return Promise { resolve, reject ->
// Simulate async operation
js("""
setTimeout(() => {
if (arguments[0] === "valid") {
arguments[1]('{"name": "Alice", "age": 25}');
} else {
arguments[2]('User not found');
}
}, 1000);
""")(userId, resolve, reject)
}
}
// Use the promise
fetchUserData("valid")
.then { userData ->
println("User data: $userData")
userData
}
.catch { error ->
println("Failed to fetch user: $error")
"{}".toJsString()
}// Chain multiple asynchronous operations
fun processDataPipeline(input: String): Promise<JsString> {
return Promise.resolve(input.toJsString())
.then { data ->
// Step 1: Validate data
println("Validating: $data")
if (data.toString().isNotEmpty()) {
data
} else {
throw Exception("Invalid data")
}
}
.then { validData ->
// Step 2: Transform data
println("Transforming: $validData")
validData.toString().uppercase().toJsString()
}
.then { transformedData ->
// Step 3: Save data
println("Saving: $transformedData")
"Saved: $transformedData".toJsString()
}
}
// Use the pipeline
processDataPipeline("hello world")
.then { result ->
println("Pipeline result: $result")
result
}
.catch { error ->
println("Pipeline error: $error")
"Error occurred".toJsString()
}// Execute multiple promises in parallel
fun fetchMultipleResources(): Promise<JsArray<out JsString>> {
val promises = arrayOf(
Promise.resolve("Resource 1".toJsString()),
Promise.resolve("Resource 2".toJsString()),
Promise.resolve("Resource 3".toJsString())
).toJsArray()
return Promise.all(promises)
}
// Wait for all to complete
fetchMultipleResources()
.then { results ->
println("All resources loaded:")
for (i in 0 until results.length) {
println("- ${results[i]}")
}
results
}
.catch { error ->
println("One or more resources failed: $error")
arrayOf<JsString>().toJsArray()
}// Implement timeout using Promise.race
fun withTimeout<T : JsAny?>(
promise: Promise<T>,
timeoutMs: Int
): Promise<T> {
val timeoutPromise = Promise<T> { _, reject ->
js("""
setTimeout(() => {
arguments[0]('Operation timed out');
}, arguments[1]);
""")(reject, timeoutMs)
}
val promises = arrayOf(promise, timeoutPromise).toJsArray()
return Promise.race(promises)
}
// Use with timeout
val slowOperation = Promise<JsString> { resolve, _ ->
js("""
setTimeout(() => {
arguments[0]('Slow operation completed');
}, 3000);
""")(resolve)
}
withTimeout(slowOperation, 2000)
.then { result ->
println("Operation completed: $result")
result
}
.catch { error ->
println("Operation failed or timed out: $error")
"timeout".toJsString()
}// Wrapper for fetch API
@JsFun("(url, options) => fetch(url, options)")
external fun jsFetch(url: String, options: JsAny?): Promise<JsAny>
fun httpGet(url: String): Promise<JsString> {
return jsFetch(url, null)
.then { response ->
// Check if response is ok
val ok = js("arguments[0].ok")(response) as Boolean
if (ok) {
js("arguments[0].text()")(response) as Promise<JsString>
} else {
Promise.reject("HTTP Error".toJsString())
}
}
.then { text ->
text
}
}
// Use the HTTP wrapper
httpGet("https://api.example.com/data")
.then { responseText ->
println("Response: $responseText")
responseText
}
.catch { error ->
println("HTTP request failed: $error")
"".toJsString()
}// Comprehensive error handling
fun robustAsyncOperation(): Promise<JsString> {
return Promise<JsString> { resolve, reject ->
try {
// Simulate operation that might throw
val result = performSomeOperation()
resolve(result.toJsString())
} catch (e: Exception) {
reject(e.message?.toJsString() ?: "Unknown error".toJsString())
}
}
.catch { jsError ->
// Convert JavaScript errors to meaningful messages
val errorMessage = when {
jsError is JsString -> jsError.toString()
else -> "Unexpected error: $jsError"
}
println("Handled error: $errorMessage")
"Error handled gracefully".toJsString()
}
}
private fun performSomeOperation(): String {
// Simulate some operation
return "Operation result"
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-stdlib-wasm-js