如何等待悬浮功能的结果?
我需要将freshcsrf
字符串添加到每个请求中。使用okhttpclient
带有authinterceptor
。问题是如何将请求发送到Interceptor中以获取freshcsrf
字符串?
在下面的代码中发生错误,
Suspend function 'getAuth' should be called only from a coroutine or another suspend function
class AuthInterceptor(val authApi: IAuthService) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val freshCsrf = authApi.getAuth().freshCsrf
// ... add freshCsrf to form body
return chain.proceed(request)
}
}
// Retrofit service
interface IAuthApi {
@GET("/auth")
suspend fun getAuth(): Auth
}
我尝试使用coroutine,但也失败了,因为等不及结果。 async/等待
案例以错误
Suspend function 'await' should be called only from a coroutine or another suspend function
private val scope = CoroutineScope(Dispatchers.IO)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val freshCsrf = scope.async { authApi.getAuth().freshCsrf }
freshCsrf.await()
// ... add freshCsrf to form body
return chain.proceed(request)
}
更新1
我与runblocking
说明相混淆的
示例之一它设计为桥梁定期阻止代码 以悬浮方式编写,用于主要功能和 测试。
在一侧,改造接口正在暂停,我需要等待网络结果,以便继续创建其他请求(桥梁 - 确定)。但是在另一边,它不是主要功能或测试。而且,许多教程和文章都说必须避免生产代码中的Runblocking
。你能解释一下吗?
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val freshCsrf = runBlocking {
return@runBlocking authApi.getAuth().freshCsrf
}
// ... add freshCsrf to form body
return chain.proceed(request)
}
I need to add freshCsrf
string to each request into form body. Uses OkHttpClient
with AuthInterceptor
. The problem is how to send request inside interceptor in order to get the freshCsrf
string?
In code below occurs error
Suspend function 'getAuth' should be called only from a coroutine or another suspend function
class AuthInterceptor(val authApi: IAuthService) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val freshCsrf = authApi.getAuth().freshCsrf
// ... add freshCsrf to form body
return chain.proceed(request)
}
}
// Retrofit service
interface IAuthApi {
@GET("/auth")
suspend fun getAuth(): Auth
}
I try to use coroutine, but also failed because can't wait result. One of example with async/await
case ended with error
Suspend function 'await' should be called only from a coroutine or another suspend function
private val scope = CoroutineScope(Dispatchers.IO)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val freshCsrf = scope.async { authApi.getAuth().freshCsrf }
freshCsrf.await()
// ... add freshCsrf to form body
return chain.proceed(request)
}
Update 1
I confused with runBlocking
description
It is designed to bridge regular blocking code to libraries that are
written in suspending style, to be used in main functions and in
tests.
In one side, retrofit interface is suspending and I need to wait network result in order to continue creating other request (bridge - ok). But in the other side, it isn't main function or test. And many tutorials and articles tell that must to avoid runBlocking
in production code. Can you explain it?
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val freshCsrf = runBlocking {
return@runBlocking authApi.getAuth().freshCsrf
}
// ... add freshCsrf to form body
return chain.proceed(request)
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您不想使用
runblocking
,则必须介绍返回call< auth>
的第二个端点。呼叫< auth>
将允许您在其上运行execute()
函数以同步(阻止)方式运行请求。呼叫接口
文档代码> call.execute :
我认为
runblocking
在这种情况下,实际上并不是一个不好的选择。作为文档状态,它用于将悬挂代码桥接到阻止范围。对我来说,主要功能和测试是常见用例。If you don't want to use
runBlocking
then you will have to introduce second endpoint that returnsCall<Auth>
in the IAuthApi interface.Call<Auth>
will allow you to runexecute()
function on it to run a request in synchronous (blocking) way.Call interface documentation
Below how it can look like using
Call.execute
:I think
runBlocking
in this case is not a bad option really. As documentation state it's used to bridge suspending code to the blocking one. Main function and tests for me are common use cases.使用
.execute()
而不是.enqueue()
,它将同步执行请求。interceptor
不需要,因为CSRF保护通常位于HMTL&lt; head&gt;
;中
如果将字符串放在HTTP标题中,这将是其他事情。
相关文档:代码> 。
Use
.execute()
instead of.enqueue()
and it will perform the request synchronously.Interceptor
is not required, as CSRF protection usually resides in the HMTL<head>
;this would be something else, if the string would be served in the HTTP headers.
The relevent documentation:
Interface Call<T>
.