2017-02-05 10 views
0

Я разработал класс Позволяет называть его AsyncClass, который реализует AsyncCalllback. Он имеет две глобальные переменные boolean flag и Object val. И конструктор выглядит следующим образом:GWT Сделать синхронный/блокирующий вызов с использованием обратного вызова Asynchronus

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

и onSuccess() функция определяется следующим образом:

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

Теперь то, что я хочу, это, чтобы получить возвращаемое значение здесь. Так что я сделать вызов:

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

и у меня есть ход время цикла, который держит в ожидании флаг, чтобы включить верно.

while(!callback.flag); 

Однако он застревает в бесконечном цикле. Почему это происходит ???

+0

Вам необходимо использовать методы onFailure и onSuccess для AsyncCallback.GWT управляется событиями, поэтому вызов будет успешным или неудачным, и один из этих методов будет вызван. Подумайте об этом как о вызове и забудьте, а затем дождитесь события, будь то onSuccess или onFailure ... – WLGfx

+0

Это именно то, что я делаю. Предполагается, что метод onSuccess включит флаг, поэтому условие while while встречается false и оно завершается. Но цикл while продолжает действовать вечно. Это потому, что объект обратного вызова удерживается текущим потоком, и пока он не отпустит его, ничего не может произойти? –

+1

Правильно - есть только один поток, поэтому нет возможности даже попробовать запустить onSuccess, пока код, который запустил вызов на сервер, не вернул управление браузеру. –

ответ

1

Вам не нужно создавать классы Async на заранее заданных onSuccess методах, вы можете просто определить их на месте.
Если вы хотите, чтобы сделать асинхронный вызов, а затем использовать возвращаемое значение после того, как вызов удается, попробуйте следующее:

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...) 
    } 
}); 

еще лучше, если ваша служба возвращает определенный тип, как String, использовать родовая версия AsyncCallback вместо сырых один:

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

После того, как сделан вызов, и если это удастся, ваш метод doSomethingWith будет называться и выполнение продолжится оттуда.


EDIT: в комментарии OP, это выглядит, как будто они пытаются реализовать синхронную вызова из клиентского кода, а не асинхронный один (несмотря на «Async» присвоения имен). Я не уверен, что это возможно с использованием библиотеки RPC GWT. Согласно this, this и this, вам придется реализовать вызовы в чистом Javascript с помощью методов JSNI. Однако вы должны заметить, что все ответы на эти вопросы рекомендуют избегать синхронных вызовов и вместо этого перейти асинхронно.

+0

Вам не хватает точки. Я хочу заблокировать, пока не получу возвращаемое значение. Проблема в том, что это единственная потоковая система, механизм блокировки не позволяет выполнять onSucess(). –

+1

Я бы сказал, что _you_ - это тот, кто не хватает точки, если вы используете ** Async ** Механизм обратного вызова для реализации ** синхронного ** вызова. В любом случае, я отредактирую свой ответ. – walen

0

Вызов, который вы делаете, является асинхронным, и вы хотите заставить его работать так, как будто это синхронизация. По моему опыту, это не очень практично, и вы могли бы хотеть, чтобы реорганизовать немного, как это:

some_code; 
make_sync_call; 
some_other_code; 

в

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

Если есть веские причины, почему вы действительно должны сделать оживленное ожидание вместо callback-based, тогда «ожидание javascript занят», вероятно, ключевые слова, которые вы ищете (например, здесь What is the JavaScript version of sleep()?)

Обратите внимание, что я настоятельно рекомендую вам и для callback-based метод.