Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

最近在嘗試 Kotlin/JS 的程式構建,遇到 Coroutine 和 Promise 的互相轉換問題。

Promise -> suspend func

從 Promise 轉換為 suspend function 是比較簡單的。Kotlin 的 suspend function 都能通過 suspendCoroutine() 暫時掛起。給 Promise 增加一個擴展函數 await()

1
2
3
4
5
6
7
suspend fun <T> Promise<T>.await() : T = suspendCoroutine { coroutine ->
then {
coroutine.resumeWith(Result.success(it))
}.catch {
coroutine.resumeWith(Result.failure(it))
}
}

suspend func -> Promise

但反過來讓 suspend function 變 Promise 則稍微有點麻煩,遂查閱 Google⋯⋯

結果發現方法還蠻簡單的。需要使用 Kotlin/JS 給 suspend 函數提供的 startCoroutine() 函數,該函數需要一個 Continuation<T> 傳入為 suspend function 提供上下文。

在此新建一個函數 promise()

1
2
3
4
5
6
7
8
9
10
11
fun <T> promise(coroutineContext : CoroutineContext = EmptyCoroutineContext, block: suspend () -> T) : Promise<Result<T>> {
return Promise { resolve, reject ->
block.startCoroutine(object : Continuation<T> {
override val context: CoroutineContext get() = coroutineContext
override fun resumeWith(result: Result<T>) {
if(result.isFailure) reject(result.exceptionOrNull() ?: Exception("Coroutine failed."))
else resolve(result)
}
})
}
}

直接把 suspend function 的 resume result 返回出去,這樣也能暴露更多控制權以及減少 promise() 函數的工作量。提供一個默認的 coroutineContext,允許以後按需切換。

以上。

评论