0

I have designed a class Lets call it AsyncClass which implements AsyncCalllback. It has two global variables boolean flag and Object val. And the constructor look like this:

AsyncClass()
{
    this.flag=false;
    this.val=null;
}

and onSuccess() function is defined as:

public void onSuccess(Object x){
      this.flag=true;
      this.val=x;
}

Now what I want is this to get a return value from here. So I make a call:

AsyncClass callback=new AsyncClass();
service.getResult(createRequestObject(),callback)

and I have a while loop running which keeps waiting for the flag to turn true.

while(!callback.flag);

However it gets stuck in an infinite loop. Why is this happening??

walen
  • 6,188
  • 2
  • 28
  • 50
Adwait Kumar
  • 1,388
  • 8
  • 19
  • You will need to use the onFailure and onSuccess methods of the AsyncCallback. GWT is event driven so the call will succeed or fail and one of those methods will be called. Think of it as a call and forget, then wait for an event whether it is onSuccess or onFailure... – WLGfx Feb 05 '17 at 20:49
  • Which is exactly what I am doing. The onSuccess method is supposed to turn the flag on, so the while loop condition is met false and it exits. But the while loop keeps on going forever. Is it because the callback object is held by the current thread, and until it releases it nothing can happen ? – Adwait Kumar Feb 05 '17 at 21:06
  • 1
    Correct - there is only one thread, so there is no way to even try to run the onSuccess until the code which has started the call to the server has returned control to the browser. – Colin Alworth Feb 05 '17 at 21:26
  • Any way around it? Using a parallel thread or something? – Adwait Kumar Feb 05 '17 at 21:28
  • What does service.getResult do? – Warren Dew Feb 06 '17 at 03:31
  • Are you trying to make your call synchron? – El Hoss Feb 06 '17 at 09:12
  • Possible duplicate of [Synchronous RPC Calls in GWT](http://stackoverflow.com/questions/7353310/synchronous-rpc-calls-in-gwt) – walen Feb 09 '17 at 14:07

2 Answers2

1

You don't need to create Async classes on advance with predefined onSuccess methods, you can just define them on the spot.
If you want to make an asynchronous call and then make use of the return value once the call succeeds, try this:

service.getResult(createRequestObject(), new AsyncCallback() {
    public void onSuccess(final Object returnedValue) {
        doSomethingWith(returnedValue);
    }
    public void onFailure(Throwable caught) {
        // code for the call failing (alert, log...)
    }
});

Better yet, if your service returns a certain type, like String, make use of the generic version of AsyncCallback instead of the raw one:

service.getResult(createRequestObject(), new AsyncCallback<String>() {
    public void onSuccess(final String returnedValue) {
        doSomethingWithString(returnedValue);
    }
    // onFail etc.
});

Once the call is made and if it succeeds, your doSomethingWith method will be called and the execution will continue from there.


EDIT: per OP's comments, it looks like they're trying to implement a synchronous call from client code, not an asynchronous one (despite the "Async" naming). I'm not sure that's possible using GWT's RPC library. According to this, this, and this, you'd have to implement the calls in pure Javascript via JSNI methods. However, you should notice that all the answers to those questions recommend to avoid synchronous calls and go asynchronous instead.

Community
  • 1
  • 1
walen
  • 6,188
  • 2
  • 28
  • 50
  • You are missing the point. I want to block, till I get a return value. The issue is since it is a single threaded system, the blocking mechanism doesn't allow the onSucess() to execute. – Adwait Kumar Feb 09 '17 at 11:05
  • 1
    I'd say _you_ are the one missing the point if you are using **Async**Callback mechanism to implement a **synchronous** call. Anyways, I'll edit my answer. – walen Feb 09 '17 at 11:50
0

The call you are making is asynchronous, and you wish to make it work as if it were sync. In my experience, this is not very practical, and you might want to refactor a little bit, like this:

some_code;
make_sync_call;
some_other_code;

into

some_code;
make_sync_call(new Receiver() {
   void onSuccess() {
      some_other_code;
   }
}

If there are solid reasons why you really need to make a busy wait instead of callback-based, then "javascript busy wait" are probably the keywords you're looking for (eg. here What is the JavaScript version of sleep()? )

Please note however that I strongly advise against it, and for the callback-based method.

Community
  • 1
  • 1
Andrei
  • 1,510
  • 2
  • 15
  • 33