2

I have a little question here.

private boolean isSomethingTrue(String param) {
    boolean result = false;
    myService.hasAlerts(param,new Callback<Boolean>(
        @Override
        public void onSuccess(Boolean hasAlerts) {
            result = hasAlerts;
        }
    });
    return result;
}

On this code, how can i return the boolean hasAlerts that is received in the callback? This doesn't work because the result variable is not final. But when it's final, it can't be modified so...

I've done something like that:

private boolean isSomethingTrue(String param) {
    class ResultHolder {
        boolean result=false;
    }
    final ResultHolder resultHolder = new ResultHolder();
    myService.findBoolean(param,new Callback<Boolean>(
        @Override
        public void onSuccess(Boolean hasAlerts) {
            resultHolder.result = hasAlerts;
        }
    });
    return resultHolder.result;
}

But is there a simpler solution to handle such a case?

I've found this problem while trying to call a GWT RPC service.

masted
  • 1,211
  • 2
  • 8
  • 14
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419

2 Answers2

3

I can think of a few variations--none of them particularly exciting. You could merge the result holder and callback into a single class and make it static if you could use it elsewhere, but it's not really an improvement.

private boolean isSomethingTrue(String param) {
    class MyCallback implements Callback<Boolean> {
        boolean result = false;
        @Override
        public void onSuccess(Boolean hasAlerts) {
            result = hasAlerts;
        }
    }
    final MyCallback callback = new MyCallback();
    myService.findBoolean(param, callback);
    return callback.result;
}

You could implement a generic synchronous Future, but that might be misleading.

Finally, if you're doing this often you could genericize the value holder.

public class Result<T> {
    private T value;
    public void set(T value) { this.value = value; }
    public T get() { return value; }
}

private boolean isSomethingTrue(String param) {
    final Result<Boolean> result = new Result<Boolean>();
    myService.findBoolean(param,new Callback<Boolean>(
        @Override
        public void onSuccess(Boolean hasAlerts) {
            result.set(hasAlerts);
        }
    });
    return result.get();
}
David Harkness
  • 35,992
  • 10
  • 112
  • 134
1

What you need is a synchronous RPC. See >here< and >here< for details.

But I would prefer to change your coding style (assumed you have access to the code that is calling isSomethingTrue()). Supposed you have some code like this calling your method isSomethingTrue:

if(isSomethingTrue("foo")) {
    doSomeCoolStuff();
}

You can transform this to a asynchronous coding style by changing it to something like this:

isSomethingTrue("foo", new Callback<Boolean>(
    @Override
    public void onSuccess(Boolean result) {
        if(result) {
            doSomeCoolStuff();
        }
    }
});

and

private void isSomethingTrue(String param, Callback callback) {
    myService.hasAlerts(param,callback);
}
Community
  • 1
  • 1
Steffen Schäfer
  • 1,126
  • 9
  • 11
  • Thanks, seems a good idea since my method is here to know if i should display a GWT button. Thus i guess i can add the code that creates the button directly in the callback since i add the button to a global variable. – Sebastien Lorber Jul 14 '12 at 17:56