英文:
Java Retrofit | Calling a method's return in a lambda expression
问题
public String userName(){
// Retrofit setup here
MyAPI service = retrofit.create(MyAPI.class);
Call<Users> call = service.getUser();
final String[] userName = {null}; // Declare a final array to hold the user name
call.enqueue(new Callback<Users>() {
@Override
public void onResponse(Call<Users> call, Response<Users> response) {
// Suppose I get what I want here:
userName[0] = response.body().getUserName();
}
@Override
public void onFailure(Call<Users> call, Throwable throwable) {
// Let's just say we return "User not found" onFailure
}
});
// Wait for the callback to complete (not recommended for production)
while (userName[0] == null) {
// You can use Retrofit's isExecuted here if desired
}
return userName[0]; // Return the user name
}
Please note that the approach of using a while loop to wait for the callback to complete is not recommended for production code, as it can lead to performance and threading issues. It's better to design your code to work asynchronously with callbacks and avoid blocking the main thread.
英文:
Suppose I have this piece of code
public String userName(){
//Retrofit setup here
MyAPI service = retrofit.create(MyAPI.class);
Call<Users> call = service.getUser();
call.enqueue(new Callback<>() {
@Override
public void onResponse(Call<Users> call, Response<Users> response) {
//suppose I get what I want here:
response.body().getUserName();
}
@Override
public void onFailure(Call<Users> call, Throwable throwable) {
//let's just say we return "User not found" onFailure
}
});
//return statement here
}
Is there a way I can have the String return statement of the userName() method in lambda expression? If not, what's the simplest way (with minimal amounts of processing) I can use to achieve this.
Retrofit has a isExecuted
method for calls so I was thinking about using that in a while loop. But I just wanted to know if there's an easier way to do it before I proceed.
Thank you.
答案1
得分: 0
不,这是不可能的。enqueue
的意思是:以异步方式执行这个操作。也就是说,不是现在,而是以后。
你在哪里写了 return statement here
?那会在 onResponse
/onFailure
方法之前执行,所以你不能把返回语句移到那里——你的方法必须在你想让返回语句在其之前运行的地方返回(因此,必须知道要返回什么),这使得那是不可能的。
这就是异步 API 的问题:与其编写代码,不如说是在与之对抗。这就是当你说'回调地狱'时人们所指的:你需要重新设计所有的代码,使得这个方法不需要返回任何值;相反,所有将依据返回值执行的代码都需要被封装在一个 lambda 中,并且传递给这个方法,这样你就可以调用那个 lambda(并将你想要返回的内容,比如 "User not found"
,作为参数传递)。
可能有办法在这里不使用 enqueue
,我会首先看看那个方法。
英文:
No, that is not possible. enqueue
means: Do this asynchronously. As in, not now, later.
Where you wrote return statement here
? That runs before the onResponse/onFailure methods do, so you can't 'move' the return statement there - your method must return (and therefore, know what to return) before the place where you want the return statement to be has even run, which makes that impossible.
This is the problem with asynchronous API: They suck to code against. This is what people are talking about when you say 'callback hell': You need to redesign all your code so that this method needs to return nothing; instead, all code that would act upon the return value needs to be packed up in a lambda and shipped to this method, so that you can invoke that lambda (and pass the thing you want to return, such as "User not found"
, as parameter instead).
There are probably ways to not use enqueue here, I'd look at that first.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论