0
# Promise Support
1
2
JavaScript Promise integration with full async/await support and error handling for asynchronous operations in Kotlin/Wasm.
3
4
## Capabilities
5
6
### Promise Class
7
8
JavaScript Promise object with comprehensive support for asynchronous operations.
9
10
```kotlin { .api }
11
/**
12
* JavaScript Promise object for asynchronous operations
13
* @param T Type of the resolved value (must extend JsAny?)
14
* @param executor Function that receives resolve and reject callbacks
15
*/
16
external class Promise<out T : JsAny?>(
17
executor: (resolve: (T) -> Unit, reject: (JsAny) -> Unit) -> Unit
18
) : JsAny
19
```
20
21
### Promise Methods
22
23
Chain operations and handle promise results with standard JavaScript Promise methods.
24
25
```kotlin { .api }
26
/**
27
* Register fulfillment handler for the promise
28
* @param onFulfilled Callback for successful resolution
29
* @return Promise<S> New promise with transformed result
30
*/
31
fun <S : JsAny?> Promise<T>.then(onFulfilled: ((T) -> S)?): Promise<S>
32
33
/**
34
* Register fulfillment and rejection handlers for the promise
35
* @param onFulfilled Callback for successful resolution
36
* @param onRejected Callback for rejection
37
* @return Promise<S> New promise with transformed result
38
*/
39
fun <S : JsAny?> Promise<T>.then(
40
onFulfilled: ((T) -> S)?,
41
onRejected: ((JsAny) -> S)?
42
): Promise<S>
43
44
/**
45
* Register rejection handler for the promise
46
* @param onRejected Callback for handling rejection
47
* @return Promise<S> New promise with handled result
48
*/
49
fun <S : JsAny?> Promise<T>.catch(onRejected: (JsAny) -> S): Promise<S>
50
51
/**
52
* Register cleanup handler that runs regardless of promise outcome
53
* @param onFinally Callback for cleanup operations
54
* @return Promise<T> Promise with same result but with cleanup
55
*/
56
fun Promise<T>.finally(onFinally: () -> Unit): Promise<T>
57
```
58
59
### Promise Companion Object
60
61
Static methods for creating and combining promises.
62
63
```kotlin { .api }
64
/**
65
* Wait for all promises to resolve
66
* @param promise Array of promises to wait for
67
* @return Promise<JsArray<out S>> Promise resolving to array of results
68
*/
69
fun <S : JsAny?> Promise.Companion.all(
70
promise: JsArray<out Promise<S>>
71
): Promise<JsArray<out S>>
72
73
/**
74
* Wait for first promise to resolve or reject
75
* @param promise Array of promises to race
76
* @return Promise<S> Promise resolving to first completed result
77
*/
78
fun <S : JsAny?> Promise.Companion.race(
79
promise: JsArray<out Promise<S>>
80
): Promise<S>
81
82
/**
83
* Create rejected promise with given reason
84
* @param e Rejection reason
85
* @return Promise<Nothing> Rejected promise
86
*/
87
fun Promise.Companion.reject(e: JsAny): Promise<Nothing>
88
89
/**
90
* Create resolved promise with given value
91
* @param e Value to resolve with
92
* @return Promise<S> Resolved promise
93
*/
94
fun <S : JsAny?> Promise.Companion.resolve(e: S): Promise<S>
95
96
/**
97
* Create resolved promise from another promise
98
* @param e Promise to resolve with
99
* @return Promise<S> Promise with same resolution
100
*/
101
fun <S : JsAny?> Promise.Companion.resolve(e: Promise<S>): Promise<S>
102
103
/**
104
* Create resolved promise with no value (void)
105
* @return Promise<Unit> Resolved promise with unit value
106
*/
107
fun Promise.Companion.resolve(): Promise<Unit>
108
```
109
110
**Usage Examples:**
111
112
### Basic Promise Creation
113
114
```kotlin
115
import kotlin.js.*
116
117
// Create a simple promise
118
val promise = Promise<JsString> { resolve, reject ->
119
val success = true // Some condition
120
if (success) {
121
resolve("Operation successful!".toJsString())
122
} else {
123
reject("Operation failed".toJsString())
124
}
125
}
126
127
// Handle the promise
128
promise
129
.then { result ->
130
println("Success: $result")
131
result
132
}
133
.catch { error ->
134
println("Error: $error")
135
"default".toJsString()
136
}
137
.finally {
138
println("Cleanup operations")
139
}
140
```
141
142
### Async Data Fetching
143
144
```kotlin
145
// Simulating an API call
146
fun fetchUserData(userId: String): Promise<JsString> {
147
return Promise { resolve, reject ->
148
// Simulate async operation
149
js("""
150
setTimeout(() => {
151
if (arguments[0] === "valid") {
152
arguments[1]('{"name": "Alice", "age": 25}');
153
} else {
154
arguments[2]('User not found');
155
}
156
}, 1000);
157
""")(userId, resolve, reject)
158
}
159
}
160
161
// Use the promise
162
fetchUserData("valid")
163
.then { userData ->
164
println("User data: $userData")
165
userData
166
}
167
.catch { error ->
168
println("Failed to fetch user: $error")
169
"{}".toJsString()
170
}
171
```
172
173
### Promise Chaining
174
175
```kotlin
176
// Chain multiple asynchronous operations
177
fun processDataPipeline(input: String): Promise<JsString> {
178
return Promise.resolve(input.toJsString())
179
.then { data ->
180
// Step 1: Validate data
181
println("Validating: $data")
182
if (data.toString().isNotEmpty()) {
183
data
184
} else {
185
throw Exception("Invalid data")
186
}
187
}
188
.then { validData ->
189
// Step 2: Transform data
190
println("Transforming: $validData")
191
validData.toString().uppercase().toJsString()
192
}
193
.then { transformedData ->
194
// Step 3: Save data
195
println("Saving: $transformedData")
196
"Saved: $transformedData".toJsString()
197
}
198
}
199
200
// Use the pipeline
201
processDataPipeline("hello world")
202
.then { result ->
203
println("Pipeline result: $result")
204
result
205
}
206
.catch { error ->
207
println("Pipeline error: $error")
208
"Error occurred".toJsString()
209
}
210
```
211
212
### Promise.all for Parallel Operations
213
214
```kotlin
215
// Execute multiple promises in parallel
216
fun fetchMultipleResources(): Promise<JsArray<out JsString>> {
217
val promises = arrayOf(
218
Promise.resolve("Resource 1".toJsString()),
219
Promise.resolve("Resource 2".toJsString()),
220
Promise.resolve("Resource 3".toJsString())
221
).toJsArray()
222
223
return Promise.all(promises)
224
}
225
226
// Wait for all to complete
227
fetchMultipleResources()
228
.then { results ->
229
println("All resources loaded:")
230
for (i in 0 until results.length) {
231
println("- ${results[i]}")
232
}
233
results
234
}
235
.catch { error ->
236
println("One or more resources failed: $error")
237
arrayOf<JsString>().toJsArray()
238
}
239
```
240
241
### Promise.race for Timeout Implementation
242
243
```kotlin
244
// Implement timeout using Promise.race
245
fun withTimeout<T : JsAny?>(
246
promise: Promise<T>,
247
timeoutMs: Int
248
): Promise<T> {
249
val timeoutPromise = Promise<T> { _, reject ->
250
js("""
251
setTimeout(() => {
252
arguments[0]('Operation timed out');
253
}, arguments[1]);
254
""")(reject, timeoutMs)
255
}
256
257
val promises = arrayOf(promise, timeoutPromise).toJsArray()
258
return Promise.race(promises)
259
}
260
261
// Use with timeout
262
val slowOperation = Promise<JsString> { resolve, _ ->
263
js("""
264
setTimeout(() => {
265
arguments[0]('Slow operation completed');
266
}, 3000);
267
""")(resolve)
268
}
269
270
withTimeout(slowOperation, 2000)
271
.then { result ->
272
println("Operation completed: $result")
273
result
274
}
275
.catch { error ->
276
println("Operation failed or timed out: $error")
277
"timeout".toJsString()
278
}
279
```
280
281
### Integration with JavaScript APIs
282
283
```kotlin
284
// Wrapper for fetch API
285
@JsFun("(url, options) => fetch(url, options)")
286
external fun jsFetch(url: String, options: JsAny?): Promise<JsAny>
287
288
fun httpGet(url: String): Promise<JsString> {
289
return jsFetch(url, null)
290
.then { response ->
291
// Check if response is ok
292
val ok = js("arguments[0].ok")(response) as Boolean
293
if (ok) {
294
js("arguments[0].text()")(response) as Promise<JsString>
295
} else {
296
Promise.reject("HTTP Error".toJsString())
297
}
298
}
299
.then { text ->
300
text
301
}
302
}
303
304
// Use the HTTP wrapper
305
httpGet("https://api.example.com/data")
306
.then { responseText ->
307
println("Response: $responseText")
308
responseText
309
}
310
.catch { error ->
311
println("HTTP request failed: $error")
312
"".toJsString()
313
}
314
```
315
316
### Error Handling Patterns
317
318
```kotlin
319
// Comprehensive error handling
320
fun robustAsyncOperation(): Promise<JsString> {
321
return Promise<JsString> { resolve, reject ->
322
try {
323
// Simulate operation that might throw
324
val result = performSomeOperation()
325
resolve(result.toJsString())
326
} catch (e: Exception) {
327
reject(e.message?.toJsString() ?: "Unknown error".toJsString())
328
}
329
}
330
.catch { jsError ->
331
// Convert JavaScript errors to meaningful messages
332
val errorMessage = when {
333
jsError is JsString -> jsError.toString()
334
else -> "Unexpected error: $jsError"
335
}
336
337
println("Handled error: $errorMessage")
338
"Error handled gracefully".toJsString()
339
}
340
}
341
342
private fun performSomeOperation(): String {
343
// Simulate some operation
344
return "Operation result"
345
}
346
```