如果有人使用同步http调用,那么可以解释将协程应用于诸如Feign之类的http客户端是否有用吗?由于它直到收到响应才被阻塞,因此编写这样的代码不会获得任何 yield (就最大程度地减少线程停机时间而言):
async {feignApi.getSomeMeaningfulData1()}
async {feignApi.getSomeMeaningfulData2()}
//And waiting for the result to combine.
我们要不要?
据我了解,在以下情况下可能会很有用:
1)http客户端在通过网络读取数据时在内部使用了某种暂停功能
suspended fun readChunkOfData()
在某个循环中,然后工作线程将不会等待空闲以等待新数据块的来临(它可以在第二个请求上工作,然后来回切换直到请求完成)。我对常规http客户端在内部的工作方式了解不多,所以我需要澄清一下。2)至少它没有等到其他服务器上处理了请求。
有可能吗?
我应该在Feign中使用Ktor框架的某些部分作为httpClient来解决此问题吗?
最佳答案
如果您在GUI应用程序中使用了Feign,即使Feign是一个阻塞API,协程也将提供很大的帮助。
从线程调用者的 Angular 来看,协程与线程池结合可以将阻塞的调用转换为挂起的调用。由于无法阻止GUI线程,因此这是一个很好的选择。您保留了完全相同的同步编程模型(返回HTTP结果的简单函数调用),但仍遵守GUI线程限制。
Android的基本示例:
class MyActivity : AppCompatActivity(), CoroutineScope {
lateinit var masterJob: Job
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + masterJob
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
masterJob = Job()
this.launch {
val github: GitHub = feignCall("https://api.github.com")
val contributors = github.contributors("OpenFeign", "feign")
findViewById<TextView>(R.id.about_text_view).text = contributors.toString()
}
}
override fun onDestroy() {
super.onDestroy()
masterJob.cancel()
}
suspend inline fun <reified T> feignCall(url: String) = withContext(Dispatchers.Default) {
Feign.builder().decoder(GsonDecoder()).target(T::class.java, url)
}
相同的推理适用于您具有顶级事件循环且每个事件处理程序必须快速完成才能维持事件处理吞吐量的任何情况。
关于kotlin - 协程程序的异步http调用(使用诸如Feign之类的http客户端),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52708374/