Enhance SuspendLazy

This commit is contained in:
Him188 2019-12-18 10:35:23 +08:00
parent 0c6e09361d
commit e90be8b93d

View File

@ -2,16 +2,18 @@
package net.mamoe.mirai.utils package net.mamoe.mirai.utils
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred import kotlinx.coroutines.Deferred
import kotlinx.coroutines.async import kotlinx.coroutines.async
import net.mamoe.mirai.contact.QQ 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` 的替代品. * 挂起初始化的 [lazy], 是属性不能 `suspend` 的替代品.
@ -27,20 +29,12 @@ fun <R> CoroutineScope.SuspendLazy(initializer: suspend () -> R): Lazy<Deferred<
* @sample QQ.profile * @sample QQ.profile
*/ */
@PublishedApi @PublishedApi
internal class SuspendLazy<R>(scope: CoroutineScope, initializer: suspend () -> R) : Lazy<Deferred<R>> { internal class SuspendLazy<R>(scope: CoroutineScope, coroutineContext: CoroutineContext = EmptyCoroutineContext, initializer: suspend () -> R) :
private val valueUpdater: Deferred<R> by lazy { scope.async { initializer() } } Lazy<Deferred<R>> {
private val valueUpdater: Deferred<R> by lazy { scope.async(context = coroutineContext) { initializer() } }
@Suppress("EXPERIMENTAL_API_USAGE")
override val value: Deferred<R> override val value: Deferred<R>
get() = if (isInitialized()) { get() = valueUpdater
CompletableDeferred(valueUpdater.getCompleted())
} else {
CompletableDeferred<R>().apply {
valueUpdater.invokeOnCompletion {
this.complete(valueUpdater.getCompleted())
}
}
}
override fun isInitialized(): Boolean = valueUpdater.isCompleted override fun isInitialized(): Boolean = valueUpdater.isCompleted
} }