gpt4 book ai didi

android - 将回调 hell 转换为延迟对象

转载 作者:太空宇宙 更新时间:2023-11-03 13:39:47 25 4
gpt4 key购买 nike

背景:所以,我有一个相当大的项目,其中包含很多 API 函数。我正在考虑完全转向协程,但由于它们是作为 Callback 而不是 Deferred 实现的,所以我无法有效地使用它们。例如:我想异步执行 apiCallOne()apiCallTwo()apiCallThree() 并调用 .await() 在更改 UI 之前等待最后一个请求完成。

现在项目结构如下:

最底部(或顶部)是ApiService.java:

interface ApiService {
@GET("...")
Call<Object> getData();
...
}

然后我有一个 ClientBase.java:function 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(...);
}
});
}

ApiCallbackApiResponse 看起来像这样:

public interface ApiCallback<T> {
void onResult(T response);
}

public class ApiResponse<T> {
private T mResult;
private ServiceError mError;
...
}

因此,在所有这些之前,我还有 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);
}
});
}

如您所见,这非常非常糟糕。我怎样才能至少传输部分代码以确保 ApiClient.java 函数返回 Deferred 对象? (我愿意为此创建另一个包装类)

最佳答案

所以一般来说,一个简单的方法是从挂起函数返回一个 suspendCancellableCoroutine,然后你可以异步完成。所以在你的情况下,你可能会写这样的东西:

suspend fun getUserName(name: String): ApiResponse<...> {
return suspendCancellableCoroutine { continuation ->
createRequest(ApiService.getData(...), new ApiCallback<ApiResponse<...>>() {
@Override
public void onResult(ApiResponse<...> response) {
continuation.resume(response)
}
});
}
}

您基本上返回一个 SettableFuture 的等价物,然后在您获得成功或失败时将其标记为完成。如果您想通过异常处理来处理错误,还有 continueWithException(Throwable)

也就是说:

由于您使用的是 Retrofit,我建议您只添加 retrofit2-kotlin-coroutines-adapter native 为您添加此支持的依赖项。

关于android - 将回调 hell 转换为延迟对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55626871/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com