<lambda>null1 package kotlinx.coroutines
2
3 import kotlin.coroutines.*
4 import kotlin.js.*
5
6 /**
7 * Starts new coroutine and returns its result as an implementation of [Promise].
8 *
9 * Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
10 * If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [Dispatchers.Default] is used.
11 * The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
12 * with corresponding [context] element.
13 *
14 * By default, the coroutine is immediately scheduled for execution.
15 * Other options can be specified via `start` parameter. See [CoroutineStart] for details.
16 *
17 * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine.
18 * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT].
19 * @param block the coroutine code.
20 */
21 public fun <T> CoroutineScope.promise(
22 context: CoroutineContext = EmptyCoroutineContext,
23 start: CoroutineStart = CoroutineStart.DEFAULT,
24 block: suspend CoroutineScope.() -> T
25 ): Promise<T> =
26 async(context, start, block).asPromise()
27
28 /**
29 * Converts this deferred value to the instance of [Promise].
30 */
31 public fun <T> Deferred<T>.asPromise(): Promise<T> {
32 val promise = Promise<T> { resolve, reject ->
33 invokeOnCompletion {
34 val e = getCompletionExceptionOrNull()
35 if (e != null) {
36 reject(e)
37 } else {
38 resolve(getCompleted())
39 }
40 }
41 }
42 promise.asDynamic().deferred = this
43 return promise
44 }
45
46 /**
47 * Converts this promise value to the instance of [Deferred].
48 */
asDeferrednull49 public fun <T> Promise<T>.asDeferred(): Deferred<T> {
50 val deferred = asDynamic().deferred
51 @Suppress("UnsafeCastFromDynamic")
52 return deferred ?: GlobalScope.async(start = CoroutineStart.UNDISPATCHED) { await() }
53 }
54
55 /**
56 * Awaits for completion of the promise without blocking.
57 *
58 * This suspending function is cancellable: if the [Job] of the current coroutine is cancelled while this
59 * suspending function is waiting on the promise, this function immediately resumes with [CancellationException].
60 * There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled
61 * while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details.
62 */
awaitnull63 public suspend fun <T> Promise<T>.await(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
64 this@await.then(
65 onFulfilled = { cont.resume(it) },
66 onRejected = { cont.resumeWithException(it as? Throwable ?: Exception("Non-Kotlin exception $it")) })
67 }
68