Pet*_*der 5 android coroutine kotlin kotlin-coroutines
背景:所以,我有一个非常大的项目,有很多 API 函数。我正在考虑完全转向协程,但由于它们被实现为Callback和不是Deferred,我无法有效地使用它们。例如:我想做apiCallOne(),apiCallTwo()和apiCallThree()async 并.await()在更改 UI 之前调用等待最后一个请求完成。
现在项目的结构是这样的:
在最底部(或顶部)是ApiService.java:
interface ApiService {
@GET("...")
Call<Object> getData();
...
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个ClientBase.java:函数createRequest()是解析改造响应的主要函数。
void getUserName(String name, ApiCallback<ApiResponse<...>> callback) {
createRequest(ApiService.getData(...), new ApiCallback<ApiResponse<?>>() {
@Override
public void onResult(ServiceResponse response) {
callback.onResult(response);
}
});
}
private void createRequest(Call call, final ApiCallback<ApiResponse<?>> callback) {
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, retrofit2.Response response) {
//heavy parsing
}
// return request results wrapped into ApiResponse object
callback.onResult(new ApiResponse<>(...));
}
@Override
public void onFailure(Call call, Throwable t) {
// return request results wrapped into ApiResponse object
callback.onResult(...);
}
});
}
Run Code Online (Sandbox Code Playgroud)
ApiCallback和ApiResponse看起来像这样:
public interface ApiCallback<T> {
void onResult(T response);
}
public class ApiResponse<T> {
private T mResult;
private ServiceError mError;
...
}
Run Code Online (Sandbox Code Playgroud)
所以,在这一切之前,我还ApiClient.java使用了ClientBase.createRequest():
public void getUserName(String name, ApiCallback<ApiResponse<..>> callback) {
ClientBase.getUserName(secret, username, new ServiceCallback<ServiceResponse<RegistrationInvite>>() {
@Override
public void onResult(ServiceResponse<RegistrationInvite> response) {
...
callback.onResult(response);
}
});
}
Run Code Online (Sandbox Code Playgroud)
如您所见,这非常非常糟糕。我如何至少传输一些代码以确保该ApiClient.java函数返回Deferred对象?(我愿意为此创建另一个包装类)
所以一般来说,一个简单的方法是suspendCancellableCoroutine从挂起函数返回 a ,然后你可以异步完成。因此,在您的情况下,您可能会编写如下内容:
suspend fun getUserName(name: String): ApiResponse<...> {
return suspendCancellableCoroutine { continuation ->
createRequest(ApiService.getData(...), new ApiCallback<ApiResponse<...>>() {
@Override
public void onResult(ApiResponse<...> response) {
continuation.resume(response)
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
您基本上返回 a 的等价物,SettableFuture然后在获得成功或失败时将其标记为完成。还有continueWithException(Throwable)如果你想通过异常处理来处理错误。
那说:
由于您使用的是 Retrofit,因此我建议您只添加retrofit2-kotlin-coroutines-adapter依赖项,该依赖项为您添加了本机支持。
| 归档时间: |
|
| 查看次数: |
2015 次 |
| 最近记录: |