xref: /aosp_15_r20/external/kotlinx.coroutines/kotlinx-coroutines-core/common/src/Deferred.kt (revision 7a7160fed73afa6648ef8aa100d4a336fe921d9a)
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