1 package kotlinx.coroutines 2 3 import kotlinx.coroutines.selects.* 4 5 /** 6 * Deferred value is a non-blocking cancellable future — it is a [Job] with a result. 7 * 8 * It is created with the [async][CoroutineScope.async] coroutine builder or via the constructor of [CompletableDeferred] class. 9 * It is in [active][isActive] state while the value is being computed. 10 * 11 * `Deferred` has the same state machine as the [Job] with additional convenience methods to retrieve 12 * the successful or failed result of the computation that was carried out. The result of the deferred is 13 * available when it is [completed][isCompleted] and can be retrieved by [await] method, which throws 14 * an exception if the deferred had failed. 15 * Note that a _cancelled_ deferred is also considered as completed. 16 * The corresponding exception can be retrieved via [getCompletionExceptionOrNull] from a completed instance of deferred. 17 * 18 * Usually, a deferred value is created in _active_ state (it is created and started). 19 * However, the [async][CoroutineScope.async] coroutine builder has an optional `start` parameter that creates a deferred value in _new_ state 20 * when this parameter is set to [CoroutineStart.LAZY]. 21 * Such a deferred can be made _active_ by invoking [start], [join], or [await]. 22 * 23 * A deferred value is a [Job]. A job in the 24 * [coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/coroutine-context.html) 25 * of [async][CoroutineScope.async] builder represents the coroutine itself. 26 * 27 * All functions on this interface and on all interfaces derived from it are **thread-safe** and can 28 * be safely invoked from concurrent coroutines without external synchronization. 29 * 30 * **`Deferred` interface and all its derived interfaces are not stable for inheritance in 3rd party libraries**, 31 * as new methods might be added to this interface in the future, but is stable for use. 32 */ 33 public interface Deferred<out T> : Job { 34 35 /** 36 * Awaits for completion of this value without blocking the thread and returns the resulting value or throws 37 * the exception if the deferred was cancelled. 38 * 39 * Unless the calling coroutine is cancelled, [await] will return the same result on each invocation: 40 * if the [Deferred] completed successfully, [await] will return the same value every time; 41 * if the [Deferred] completed exceptionally, [await] will rethrow the same exception. 42 * 43 * This suspending function is itself cancellable: if the [Job] of the current coroutine is cancelled or completed 44 * while this suspending function is waiting, this function immediately resumes with [CancellationException]. 45 * 46 * This means that [await] can throw [CancellationException] in two cases: 47 * - if the coroutine in which [await] was called got cancelled, 48 * - or if the [Deferred] itself got completed with a [CancellationException]. 49 * 50 * In both cases, the [CancellationException] will cancel the coroutine calling [await], unless it's caught. 51 * The following idiom may be helpful to avoid this: 52 * ``` 53 * try { 54 * deferred.await() 55 * } catch (e: CancellationException) { 56 * currentCoroutineContext().ensureActive() // throws if the current coroutine was cancelled 57 * processException(e) // if this line executes, the exception is the result of `await` itself 58 * } 59 * ``` 60 * 61 * There is a **prompt cancellation guarantee**: even if this function is ready to return the result, but was cancelled 62 * while suspended, [CancellationException] will be thrown. See [suspendCancellableCoroutine] for low-level details. 63 * 64 * This function can be used in [select] invocations with an [onAwait] clause. 65 * Use [isCompleted] to check for completion of this deferred value without waiting, and 66 * [join] to wait for completion without returning the result. 67 */ awaitnull68 public suspend fun await(): T 69 70 /** 71 * Clause using the [await] suspending function as a [select] clause. 72 * It selects with the deferred value when the [Deferred] completes. 73 * If [Deferred] completes with an exception, the whole the [select] invocation fails with the same exception. 74 * Note that, if [Deferred] completed with a [CancellationException], throwing it may have unintended 75 * consequences. See [await] for details. 76 */ 77 public val onAwait: SelectClause1<T> 78 79 /** 80 * Returns *completed* result or throws [IllegalStateException] if this deferred value has not 81 * [completed][isCompleted] yet. It throws the corresponding exception if this deferred was [cancelled][isCancelled]. 82 * 83 * This function is designed to be used from [invokeOnCompletion] handlers, when there is an absolute certainty that 84 * the value is already complete. See also [getCompletionExceptionOrNull]. 85 * 86 * **Note: This is an experimental api.** This function may be removed or renamed in the future. 87 */ 88 @ExperimentalCoroutinesApi 89 public fun getCompleted(): T 90 91 /** 92 * Returns *completion exception* result if this deferred was [cancelled][isCancelled] and has [completed][isCompleted], 93 * `null` if it had completed normally, or throws [IllegalStateException] if this deferred value has not 94 * [completed][isCompleted] yet. 95 * 96 * This function is designed to be used from [invokeOnCompletion] handlers, when there is an absolute certainty that 97 * the value is already complete. See also [getCompleted]. 98 * 99 * **Note: This is an experimental api.** This function may be removed or renamed in the future. 100 */ 101 @ExperimentalCoroutinesApi 102 public fun getCompletionExceptionOrNull(): Throwable? 103 } 104