挂起呼叫直到设置值

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
    }
}