【发布时间】:2021-09-23 18:08:04
【问题描述】:
这个问题是在与同事广泛讨论后提出的,
问题如下:
在suspendCoroutine块中调用同步方法之前我在做的事情:
private suspend fun <T : Any> request(queryRequest: GraphQLQueryRequest<T>): T? = suspendCoroutine { continuation ->
val response = graphqlClient.executeQuery(queryRequest.query, queryRequest.variables, executor)
val item = response.extractValueAsObject("data.${queryRequest.pathAccessor}", queryRequest.type.java)
continuation.resume(item)
}
他声称我的代码没有阻止线程被阻塞,整个过程必须等待我的协程恢复才能释放线程。
他的提议:
private suspend fun <T : Any> request(queryRequest: GraphQLQueryRequest<T>): T? {
val response = graphqlClient.reactiveExecuteQuery(queryRequest.query, queryRequest.variables, executor)
return response.awaitSingle().extractValueAsObject("data.${queryRequest.pathAccessor}", queryRequest.type.java)
}
reactiveExecuteQuery() 将返回 WebFlux Mono,然后我们调用.awaitSingle() 将 Mono 转换为挂起函数,他声称这种方法与第一种不同,不会阻塞线程,一切都会正常工作。
根据documentation的suspendCoroutine
Obtains the current continuation instance inside suspend functions and suspends the currently running coroutine.
是否有人对 Kotlin 协程有更深入的了解,是否知道这些解决方案是否真的提供了不同的结果?就没有阻塞线程的阻塞而言?
如果这不是 suspendCoroutine 的用例,那会是什么?
提前感谢您的任何回复:)
【问题讨论】:
-
你使用的graphql客户端是什么?如果 executeQuery 不是挂起函数,那么您的同事是对的。你的解决方案会阻塞一个线程。
-
suspendCoroutine 用于将基于回调的 API 转换为协程
-
“不要阻塞事件总线”——我认为阻塞协程不是一个好的设计。让 Kotlin 管理它们。
标签: kotlin asynchronous spring-webflux kotlin-coroutines suspend