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