Java改造|在lambda表达式中调用方法的返回

Java改造|在lambda表达式中调用方法的返回,java,android,retrofit,Java,Android,Retrofit,假设我有这段代码 public String userName(){ //Retrofit setup here MyAPI service = retrofit.create(MyAPI.class); Call<Users> call = service.getUser(); call.enqueue(new Callback<>() { @Override public vo

假设我有这段代码

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
}

有没有办法在lambda表达式中使用userName方法的String return语句?如果没有,我可以使用哪种最简单的方法,以最少的处理量来实现这一点

改型有一个isExecuted调用方法,所以我考虑在while循环中使用它。但我只是想知道在我继续之前有没有更简单的方法。 谢谢。

不,那是不可能的。排队意味着:异步执行此操作。比如说,不是现在,而是以后

你在哪里写的回执?它在onResponse/onFailure方法之前运行,因此您不能将return语句“移动”到那里-您的方法必须返回,因此,在您希望返回语句的位置运行之前,您知道要返回什么,这使得这不可能

这就是异步API的问题:它们很难针对它们进行编码。这就是当你说“回调地狱”时人们所说的:你需要重新设计你的所有代码,这样这个方法就不需要返回任何东西;相反,所有作用于返回值的代码都需要打包在lambda中并发送到此方法,这样您就可以调用该lambda并将要返回的内容(例如User not found)作为参数传递


这里可能有一些不使用排队的方法,我先来看看。

当然可以。不使用匿名回调类,您可以创建一个通用回调类,该类适用于任何请求

private class RetroCallback<T> implements  Callback<T>{
        private Consumer<Response<T>> acceptFn;

        public RetroCallback(Consumer<Response<T>> acceptFn){
            this.acceptFn = acceptFn;
        }

        @Override
        public void onResponse(Call<T> call, Response<T> response) {
            Log.d(LOG_TAG, "Request was: " + call.request().toString());
            if(response.isSuccessful()){
                Log.d(LOG_TAG, "Response SUCCESS: " + response.toString());
            }else{
                Log.d(LOG_TAG, "Response FAILED: " + response.toString());
                //TODO: print error message or similar
                return;
            }

            //TODO: Do stuff that you would normally do on every callback, e.g. print message of "payload DTO" or similar

            // Call the lambda
            if(acceptFn != null)
                acceptFn.accept(response);
        }

        @Override
        public void onFailure(Call<T> call, Throwable t) {
            Log.d(LOG_TAG, "Request failed: " + call.request().toString() + " -> " + t.getMessage());
            //TODO: Do your error handling
        }
    }
或: 如果您不想添加这些包装,只需直接调用enqueue方法并将RetroCallback与lambda一起传递:

WebController.with(getApplicationContext()).customerController.getAllCustomer().enqueue(new RetroCallback(responseDto ->
    {
         //YOUR CODE...
    }
));

我不能在这里重新设计代码,因为我正在使用一个AWS库,我刚刚提供了一个最小的可复制示例。但我明白了。但是是的,谢谢你的帮助。让我看看不使用排队的方法。谢谢你哦。调用还执行了同步执行作业的操作。只是要在上面换一下
WebController.with(getApplicationContext()).getAllCustomer(payloadDtoResponse -> {
            if (payloadDtoResponse.isSuccessful()) {
                //TODO: Do your stuff
            }
        });
WebController.with(getApplicationContext()).customerController.getAllCustomer().enqueue(new RetroCallback(responseDto ->
    {
         //YOUR CODE...
    }
));