我正在调用API,并将响应主体分配给Retrofit的enqueue()
中的一个对象,问题是入队完成的速度太快,无法在函数的return语句之前分配值身体被称为。
以前,我以前使用过MutableLiveData
,因为它一直在观察数据,并且在更改数据时毫无问题地分配它,但是现在我不想使用任何MutableLiveData或Observables,因为我正在尝试在屏幕上实际绘制任何UI之前准备数据。
fun getResponse(
weatherLocationCoordinates: WeatherLocation
): RequestResponse {
weatherApiService.getCurrentWeather(
weatherLocationCoordinates.latitude,
weatherLocationCoordinates.longitude
).enqueue(object : Callback<WeatherResponse> {
override fun onResponse(
call: Call<WeatherResponse>,
response: Response<WeatherResponse>
) {
if (response.isSuccessful) {
// This where I do the assigning
requestResponse = RequestResponse(response.body(), true)
}
}
override fun onFailure(call: Call<WeatherResponse>, t: Throwable) {
requestResponse = RequestResponse(null, false)
}
})
// When this is called, enqueue is still not finished
// therefore I get the wrong value, I get the previously set initialization value of the obj.
return requestResponse
}
我应该使用回调或其他功能吗?我不确定如何实现回调。
答案 0 :(得分:1)
在评论之后,这里有一个回调方法:
假设我们将方法签名更改为:
fun getResponse(
weatherLocationCoordinates: WeatherLocation,
onSuccess: (WeatherResponse) -> Unit = {},
onError: (Throwable) -> Unit = {}
) {
weatherApiService.getCurrentWeather(
weatherLocationCoordinates.latitude,
weatherLocationCoordinates.longitude
).enqueue(object : Callback<WeatherResponse> {
override fun onResponse(
call: Call<WeatherResponse>,
response: Response<WeatherResponse>
) {
if (response.isSuccessful) {
onSuccess(response.body())
} else {
onError(CustomHttpExceptionWithErrorDescription(response))
}
}
override fun onFailure(call: Call<WeatherResponse>, t: Throwable) {
onError(t)
}
})
}
CustomHttpExceptionWithErrorDescription
必须是您编写的代码,可以简单地解析从服务器获取的错误。不是2XX状态代码的任何内容
此方法接受两个额外的参数-一个在成功时被调用,另一个在错误时被调用。想法是这样称呼它:
getResponse(
weatherLocationCoordinates,
onSuccess = {
// do something with response
},
onError = {
// do something with the error
}
)
因为它们具有默认参数,所以您实际上不需要同时指定两个回调。只是您感兴趣的一个。示例:
// react only to successes
getResponse(
weatherLocationCoordinates,
onSuccess = {
// do something with response
}
)
// react only to errors
getResponse(weatherLocationCoordinates) {
// do something with the error
}
// just call the network calls and don't care about success or error
getResponse(weatherLocationCoordinates)