Kotlinx 协程 - 与旧版 Lamda 语法集成
Kotlinx Coroutines - Integrate with legacy Lamda Syntax
考虑以下我无法重构的第 3 方函数:
fun doSomethingAsyncWithLamdas(completion: (Throwable?) -> Unit) {...}
从挂起函数调用(并等待)这个以 lamda 为中心的函数的正确方法是什么?
Note: I'm using Kotlin Multiplatform's Kotlinx Coroutines, not sure if an answer might depend on that.
我能想到的最好的方法是使用 Mutex:
suspend fun waitForBlock(block: ((Throwable?) -> Unit) -> Unit) {
val mutex = Mutex(locked = true)
block { throwable ->
throwable?.let { throw it }
mutex.unlock()
}
// Wait for the unlock
mutex.lock()
}
用法示例:
suspend fun myAwesomeSuspendFunc() {
// Do stuff
waitForBlock { completion ->
doSomethingAsyncWithLamdas { exception ->
completion(exception)
}
}
// Do other stuff
}
您正在寻找的似乎是一种将 callback-based API 包装成适合协程的 suspend
函数的方法。
您要找的函数存在,它叫做 suspendCancellableCoroutine。
你可以这样使用它:
// assuming this is given
fun doSomethingAsyncWithLambdas(completion: (Throwable?) -> Unit) {...}
// you can declare this
suspend fun mySuspendWrapper(): Unit = suspendCancellableCoroutine { cont ->
doSomethingAsyncWithLambdas { th ->
if (th == null) {
cont.resume(Unit)
} else {
cont.resumeWithException(th)
}
}
}
考虑以下我无法重构的第 3 方函数:
fun doSomethingAsyncWithLamdas(completion: (Throwable?) -> Unit) {...}
从挂起函数调用(并等待)这个以 lamda 为中心的函数的正确方法是什么?
Note: I'm using Kotlin Multiplatform's Kotlinx Coroutines, not sure if an answer might depend on that.
我能想到的最好的方法是使用 Mutex:
suspend fun waitForBlock(block: ((Throwable?) -> Unit) -> Unit) {
val mutex = Mutex(locked = true)
block { throwable ->
throwable?.let { throw it }
mutex.unlock()
}
// Wait for the unlock
mutex.lock()
}
用法示例:
suspend fun myAwesomeSuspendFunc() {
// Do stuff
waitForBlock { completion ->
doSomethingAsyncWithLamdas { exception ->
completion(exception)
}
}
// Do other stuff
}
您正在寻找的似乎是一种将 callback-based API 包装成适合协程的 suspend
函数的方法。
您要找的函数存在,它叫做 suspendCancellableCoroutine。
你可以这样使用它:
// assuming this is given
fun doSomethingAsyncWithLambdas(completion: (Throwable?) -> Unit) {...}
// you can declare this
suspend fun mySuspendWrapper(): Unit = suspendCancellableCoroutine { cont ->
doSomethingAsyncWithLambdas { th ->
if (th == null) {
cont.resume(Unit)
} else {
cont.resumeWithException(th)
}
}
}