从回调返回字符串 - Java

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6847870/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 17:34:31  来源:igfitidea点击:

return String from a callback - Java

javastringcallbackreturn

提问by ph09

does anyone know how I can solve the following problem. I want to return a String from a callback, but I get only "The final local variable s cannot be assigned, since it is defined in an enclosing type", because of final.

有谁知道我如何解决以下问题。我想从回调中返回一个字符串,但由于 final,我只得到“无法分配最终局部变量 s,因为它是在封闭类型中定义的”。

 public String getConstraint(int indexFdg) {
    final String s;
    AsyncCallback<String> callback = new AsyncCallback<String>() {
        public void onFailure(Throwable caught) {
            caught.printStackTrace();
        }

        public void onSuccess(String result) {
            s = result;
        }
    };
    SpeicherService.Util.getInstance().getConstraint(indexFdg, callback);
    return s;
    }

回答by Mark Peters

The whole point of an asynchronous callback is to notify you of something that happens asynchronously, at some time in the future. You can't return sfrom getConstraintif it's going to be set afterthe method has finished running.

异步回调的全部意义在于通知您异步发生的事情,在未来的某个时间。如果在方法运行完成要设置它sgetConstraint则无法返回。

When dealing with asynchronous callbacks you have to rethink the flow of your program. Instead of getConstraintreturning a value, the code that would go on to usethat value should be called as a result of the callback.

在处理异步回调时,您必须重新考虑程序的流程。应该作为回调的结果调用getConstraint将继续使用该值的代码,而不是返回一个值。

As a simple (incomplete) example, you would need to change this:

作为一个简单(不完整)的例子,你需要改变这个:

 String s = getConstraint();
 someGuiLabel.setText(s);

Into something like this:

变成这样:

 myCallback = new AsyncCallback<String>() {
     public void onSuccess(String result) {
         someGuiLabel.setText(result);
     }
 }
 fetchConstraintAsynchronously(myCallback);

Edit

编辑

A popular alternative is the concept of a future. A future is an object that you can return immediately but which will only have a value at some point in the future. It's a container where you only need to wait for the value at the point of asking for it.

一个流行的替代方案是未来的概念。未来是一个可以立即返回的对象,但它只会在未来的某个时间点有一个值。这是一个容器,您只需要在请求它时等待该值。

You can think of holding a future as holding a ticket for your suit that is at the dry cleaning. You get the ticket immediately, can keep it in your wallet, give it to a friend... but as soon as you need to exchange it for the actual suit you need to wait until the suit is ready.

你可以把持有未来想象成持有一张干洗店西装的票。你立即拿到票,可以把它放在你的钱包里,把它送给朋友……但是一旦你需要用它来换取真正的西装,你就需要等到西装准备好了。

Java has such a class (Future<V>) that is used widely by the ExecutorService API.

Java 有一个Future<V>ExecutorService API广泛使用的类 ( ) 。

回答by songlebao

An alternative workaround is to define a new class, called SyncResult

另一种解决方法是定义一个新类,称为 SyncResult

public class SyncResult {
    private static final long TIMEOUT = 20000L;
    private String result;

    public String getResult() {
        long startTimeMillis = System.currentTimeMillis();
        while (result == null && System.currentTimeMillis() - startTimeMillis < TIMEOUT) {
            synchronized (this) {
                try {
                    wait(TIMEOUT);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public void setResult(String result) {
        this.result = result;
        synchronized (this) {
            notify();
        }
    }
}

Then change your code to this

然后将您的代码更改为此

public String getConstraint(int indexFdg) {
    final SyncResult syncResult = new SyncResult();
    AsyncCallback<String> callback = new AsyncCallback<String>() {
        public void onFailure(Throwable caught) {
            caught.printStackTrace();
        }

        public void onSuccess(String result) {
            syncResult.setResult(result);
        }
    };
    SpeicherService.Util.getInstance().getConstraint(indexFdg, callback);
    return syncResult.getResult();
}

The getResult()method will be blocked until setResult(String)method been called or the TIMEOUTreached.

getResult()方法将被阻塞,直到setResult(String)方法被调用或TIMEOUT到达。