从协程获取状态更新

问题描述 投票:2回答:2

考虑一个报告其操作进度的异步API:

suspend fun operationWithIO(input: String, progressUpdate: (String) -> Unit): String {
    withContext(Dispatchers.IO) {
        // ...
    }
}

是否可以实现对progressUpdate的调用,以便在调用者的调度程序上处理回调?或者有更好的方法将状态更新传递给调用者吗?

kotlin callback kotlinx.coroutines
2个回答
2
投票

您应该在频道上发送进度更新。这将允许呼叫者使用它想要的任何调度员来收听频道。

suspend fun operationWithIO(input: String, progressChannel: Channel<String>): String {
    withContext(Dispatchers.IO) {
        // ...

        progressChannel.send("Done!")
        progressChannel.close()
    }
}

调用者可以通过执行以下操作来使用它:

val progressChannel = Channel<String>()

someScope.launch {
    operationWithIO(input, progressChannel)
}

// Remember the call to progressChannel.close(), so that this iteration stops.
for (progressUpdate in progressChannel) {
    println(progressUpdate)
}

0
投票

如何包装回调函数并调用包装函数:

/** Return a new callback that invokes this callback on the current context. */
suspend fun <T> ((T) -> Unit).onCurrentContext(): (T) -> Unit =
    coroutineContext.let { context ->
        { value: T ->
            runBlocking {
                launch(context) {
                    [email protected](value)
                }
            }
        }
    }

/** Perform a background operation, delivering status updates on the caller's context. */
suspend fun operationWithIO(statusUpdate: (String) -> Unit): String {
    val cb = statusUpdate.onCurrentContext()
    return withContext(Dispatchers.IO) {
        cb("Phase 1")
        delay(150)
        cb("Phase 2")
        delay(150)
        "Result"
    }
}

// In use
runBlocking {
    val result = operationWithIO {
        println("received callback status $it")
    }
    println("result is $result")
}
© www.soinside.com 2019 - 2024. All rights reserved.