【问题标题】:return String from a callback - Java从回调中返回字符串 - 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; 来获取返回值。

标签: java string callback return


【解决方案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 等模式中很常见(视图和控制器相互了解)。
    猜你喜欢
    • 1970-01-01
    • 2016-10-27
    • 2014-06-30
    • 1970-01-01
    • 2016-05-19
    • 1970-01-01
    • 2014-09-25
    • 1970-01-01
    • 2019-03-13
    相关资源
    最近更新 更多