挂起呼叫直到设置值
Suspend a call until a value is set
我希望 class UploadWorker
从 class Manager
中检索一个值,但该值可能尚未在 Manager
中准备好。所以我希望 class UploadWorker
等到设置该值。
class UploadWorker(appContext: Context, workerParams: WorkerParameters):
Worker(appContext, workerParams) {
override fun doWork(): Result {
Manager.isReady()
return Result.success()
}
}
object Manager {
private lateinit var isReady
fun initialize(context: Context, myData: MyData) {
...
isReady = true
}
suspend fun isReady() {
if(::isReady.isInitialized()
return isReady
else // wait here until initialized
}
}
在其他情况下,如果我能以某种方式 suspend
或等到我的 MyApplication
class 调用 initialize()
。有什么想法吗?
您可以使用StateFlow
传递初始化状态:
val isReady = MutableStateFlow(false)
// to wait:
if (isReady.value) return true
else isReady.first { it } // it == true
// to notify:
isReady.value = true
虽然 StateFlows 非常轻量级,但是如果你想把它做的更轻但以一种丑陋的方式(直接使用协程内部):
val conts = mutableListOf<Continuation<Boolean>>()
private lateinit var isReady = false
set(value) {
if (value) conts.forEach { it.resume(true) }.also { conts.clear() }
field = value
}
// to wait:
if (isReady) return true
else suspendCancellableCoroutine { cont ->
conts.add(cont)
invokeOnCancellation { conts.remove(cont) }
}
// to notify:
isReady = true
CompletableDeferred
在这种情况下非常方便。
您的代码可能如下所示:
object Manager {
private val initialized = CompletableDeferred<Unit>()
fun initialize(context: Context, myData: MyData) {
...
initialized.complete(Unit)
}
suspend fun awaitInitialized() {
initialized.await()
// initialization is done at this point
}
}
我希望 class UploadWorker
从 class Manager
中检索一个值,但该值可能尚未在 Manager
中准备好。所以我希望 class UploadWorker
等到设置该值。
class UploadWorker(appContext: Context, workerParams: WorkerParameters):
Worker(appContext, workerParams) {
override fun doWork(): Result {
Manager.isReady()
return Result.success()
}
}
object Manager {
private lateinit var isReady
fun initialize(context: Context, myData: MyData) {
...
isReady = true
}
suspend fun isReady() {
if(::isReady.isInitialized()
return isReady
else // wait here until initialized
}
}
在其他情况下,如果我能以某种方式 suspend
或等到我的 MyApplication
class 调用 initialize()
。有什么想法吗?
您可以使用StateFlow
传递初始化状态:
val isReady = MutableStateFlow(false)
// to wait:
if (isReady.value) return true
else isReady.first { it } // it == true
// to notify:
isReady.value = true
虽然 StateFlows 非常轻量级,但是如果你想把它做的更轻但以一种丑陋的方式(直接使用协程内部):
val conts = mutableListOf<Continuation<Boolean>>()
private lateinit var isReady = false
set(value) {
if (value) conts.forEach { it.resume(true) }.also { conts.clear() }
field = value
}
// to wait:
if (isReady) return true
else suspendCancellableCoroutine { cont ->
conts.add(cont)
invokeOnCancellation { conts.remove(cont) }
}
// to notify:
isReady = true
CompletableDeferred
在这种情况下非常方便。
您的代码可能如下所示:
object Manager {
private val initialized = CompletableDeferred<Unit>()
fun initialize(context: Context, myData: MyData) {
...
initialized.complete(Unit)
}
suspend fun awaitInitialized() {
initialized.await()
// initialization is done at this point
}
}