• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download

<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