Commit e90be8b9 authored by Him188's avatar Him188

Enhance SuspendLazy

parent 0c6e0936
......@@ -2,16 +2,18 @@
package net.mamoe.mirai.utils
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async
import net.mamoe.mirai.contact.QQ
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
/**
* 创建一个在当前 [CoroutineScope] 下执行的 [SuspendLazy]
* 创建一个在当前 [CoroutineScope] 下执行初始化的 [SuspendLazy]
*/
fun <R> CoroutineScope.SuspendLazy(initializer: suspend () -> R): Lazy<Deferred<R>> = SuspendLazy(this, initializer)
fun <R> CoroutineScope.SuspendLazy(context: CoroutineContext = EmptyCoroutineContext, initializer: suspend () -> R): Lazy<Deferred<R>> =
SuspendLazy(this, context, initializer)
/**
* 挂起初始化的 [lazy], 是属性不能 `suspend` 的替代品.
......@@ -27,20 +29,12 @@ fun <R> CoroutineScope.SuspendLazy(initializer: suspend () -> R): Lazy<Deferred<
* @sample QQ.profile
*/
@PublishedApi
internal class SuspendLazy<R>(scope: CoroutineScope, initializer: suspend () -> R) : Lazy<Deferred<R>> {
private val valueUpdater: Deferred<R> by lazy { scope.async { initializer() } }
internal class SuspendLazy<R>(scope: CoroutineScope, coroutineContext: CoroutineContext = EmptyCoroutineContext, initializer: suspend () -> R) :
Lazy<Deferred<R>> {
private val valueUpdater: Deferred<R> by lazy { scope.async(context = coroutineContext) { initializer() } }
@Suppress("EXPERIMENTAL_API_USAGE")
override val value: Deferred<R>
get() = if (isInitialized()) {
CompletableDeferred(valueUpdater.getCompleted())
} else {
CompletableDeferred<R>().apply {
valueUpdater.invokeOnCompletion {
this.complete(valueUpdater.getCompleted())
}
}
}
get() = valueUpdater
override fun isInitialized(): Boolean = valueUpdater.isCompleted
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment