将回调地狱转换为延迟对象

编程入门 行业动态 更新时间:2024-10-17 21:29:13
本文介绍了将回调地狱转换为延迟对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

背景 :因此,我有一个很大的项目,具有很多API函数.我正在考虑完全使用协程,但是由于将它们实现为Callback而不是Deferred,因此我无法高效使用它们.例如:我想执行apiCallOne(),apiCallTwo()和apiCallThree()异步并调用.await(),直到最后一个请求完成,然后再更改UI.

Background: So, I have a pretty big project with a lot of API functions. I'm thinking of completely moving to coroutines, but as they are implemented as Callback and not Deferred, I can not use them efficiently. For instance: I would like to do apiCallOne(), apiCallTwo() and apiCallThree() async and call .await() to wait till the last request is completed before changing UI.

现在,项目的结构如下:

Now the project is structured like this:

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

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

然后我有一个ClientBase.java: 函数createRequest()是解析改造响应的主要函数.

Then I have a ClientBase.java: function createRequest() is main function for parsing retrofit response.

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(...); } }); }

ApiCallback和ApiResponse看起来像这样:

public interface ApiCallback<T> { void onResult(T response); } public class ApiResponse<T> { private T mResult; private ServiceError mError; ... }

因此,在所有这些之前,我还使用了ApiClient.java的ApiClient.java:

So, before all of this, I have also ApiClient.java which uses 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对象? (我愿意为此创建另一个包装器类)

As you can see, this is very, very bad. How can I transfer some of this code at least to make sure, that ApiClient.java function return Deferred objects? (I'm willing to create another wrapper class for this)

推荐答案

因此,通常,执行此操作的一种简单方法是从挂起函数返回suspendCancellableCoroutine,然后可以异步完成该操作.因此,在您的情况下,您可能会编写类似以下内容的

So in general, a simple way to do this is to return a suspendCancellableCoroutine from a suspending function, which you can then complete asynchronously. So in your case, you might write something like:

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).

You basically return the equivalent of a SettableFuture and then mark it complete when you get success or failure. There's also continueWithException(Throwable) if you want to handle errors via exception handling.

说:

由于您使用的是Retrofit,因此建议您仅添加 retrofit2-kotlin -coroutines-adapter 依赖关系,从而在本机上为您添加了这种支持.

Since you're using Retrofit, I would recommend just adding in the retrofit2-kotlin-coroutines-adapter dependency which adds in this support for you natively.

更多推荐

将回调地狱转换为延迟对象

本文发布于:2023-11-25 15:19:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1630270.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:转换为   回调   地狱   对象

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!