从回调中返回字符串 - Java

Posted

技术标签:

【中文标题】从回调中返回字符串 - Java【英文标题】:return String from a callback - Java 【发布时间】:2011-10-14 10:35:45 【问题描述】:

有谁知道我可以如何解决以下问题。我想从回调中返回一个字符串,但由于 final.

 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;
    

【问题讨论】:

AsyncCallback 无法返回值。但是Callable&lt;T&gt; 可以。通常我会做的就是将其设为Callable,将其传递给执行器服务,然后使用返回的Future&lt;T&gt; 来获取返回值。 【参考方案1】:

另一种解决方法是定义一个新类,称为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();
        
    

然后把你的代码改成这个

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

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

【讨论】:

【参考方案2】:

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

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

作为一个简单(不完整)的示例,您需要更改以下内容:

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

变成这样:

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

编辑

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

您可以将持有未来视为持有您正在干洗的西装的门票。你马上拿到票,可以把它放在你的钱包里,把它送给朋友……但是一旦你需要把它换成真正的西装,你需要等到西装准备好。

Java 有这样一个类 (Future&lt;V&gt;),被 ExecutorService API 广泛使用。

【讨论】:

我面临着类似的问题,从回调的结果来看,我必须更新 UI。我采用了与您提到的相同的技术,但在我的情况下,问题已经像 A -> B 和 B -> A 一样循环,其中 A 是 UI 类,B 是具有回调的类。保持这种方式是一种好习惯,还是您可以提出任何其他替代方案?就像 UI 类调用回调,回调再次调用 UI。 @AtulKumar:我们可能需要更多细节才能知道这是否是一个问题。如果它导致了一个具体的问题,那么用一个可以重现问题的最小示例提出一个问题可能是合适的。如果您一般询问设计,它可能适合codereview.stackexchange.com。一般来说,我会说相互依赖本身并不破坏交易,并且在 MVC 等模式中很常见(视图和控制器相互了解)。

以上是关于从回调中返回字符串 - Java的主要内容,如果未能解决你的问题,请参考以下文章

从本机 c 代码 (JNI) 为 Java 中的回调函数传递多个参数

WebMethod 返回 JSON 但我的 $.ajax() 回调中的响应 obj 只是一个字符串

使用回调返回字符串

从 glutKeyboardFunc 回调函数中寻找未修改的键盘输入

Unity 中的回调 OnStreamMessageHandler 仅返回西里尔字符串的一半

从 node.js 返回文件的解析输出