2013-06-21 2 views
-1

вот мой код до сих пор (это с помощью GWT):метод GWT возвращает до того RequestBuilder Ajax вызова завершает

private ArrayList<tObjects> getSuggestions(String query) 
{ 
    // Clear previous suggestions 
    Window.alert("Clearing arraylist"); 
    arrayList.clear(); 
    query = query.toUpperCase().replace(" ", ""); 

    RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, "xmlfile.php?query="+query); 
    rb.setHeader("Content-Type", "application/x-www-form-urlencoded"); 

    try 
    { 
     rb.sendRequest(null, new RequestCallback() 
     { 

      @Override 
      public void onResponseReceived(com.google.gwt.http.client.Request request, com.google.gwt.http.client.Response response) 
      { 
       Window.alert(response.getText()); 

        // Do a lot of data processing here. 
        Window.alert("Adding to arraylist"); 
        addToArrayList(data); 


       } 

      } 

      @Override 
      public void onError(com.google.gwt.http.client.Request request, Throwable exception) 
      { 
       // TODO Auto-generated method stub 

      } 
     }); 
    } 
    catch(RequestException e) 
    { 
     Window.alert(e.toString()); 
    } 
    Window.alert("Returning arraylist. "+arrayList.toString()); 
    return arrayList; 
} 

я получаю ответ правильно, но метод возвращает (пустой) ArrayList перед добавлением. Если я удалю arrayList.clear(), на следующем ajax-вызове я вижу результат предыдущего вызова. Когда я смотрю предупреждения, огонь в следующем порядке:

1) «Очистка списка элементов массива».

2) «Возвращение массива».

3) Alert с правильным ответом с AJAX

4) «Добавление к ArrayList»

Похоже, что этот метод не дожидаясь Аякса завершить до возвращения и заканчивая метод. Как я могу заставить его дождаться заполнения массива ajax & массива, прежде чем я получу оператор return?

Спасибо!

ответ

0

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

Как правило, это делается путем ввода логики внутри метода onResponseReceived() или передачи обратного вызова, который будет вызываться, или с помощью события.

0

AJAX означает Asynchronous Javascript And XML

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

В вашем примере

rb.sendRequest 

вернется почти мгновенно, до получения ответа.

Именно поэтому вы передаете методы обратных вызовов в качестве параметров (метод onResponseReceived и метод onError). Обратные вызовы будут вызваны после того, как ваш запрос будет обработан сервером, и ваш ответ будет отправлен обратно вашему клиенту.

Теперь, если вы хотите что-то выполнить после вызова метода обратного вызова (после получения вашего массива), вы можете/должны использовать события. В вашем методе обратного вызова onResponseReceived вы можете выполнить пожар и событие, например ArrayListReceived. Вы слушаете это событие в своем классе или любом другом классе, использующем один и тот же eventbus, и делайте то, что когда-либо захотите сделать с этим массивом.

Именно поэтому автобус событий настолько полезен.

Кстати, вы не должны пытаться совершать синхронные вызовы в веб-приложении, так как это может заморозить вашего клиента, ожидая ответа. Поскольку Javascript является однопоточным (я не знаю, что веб-рабочие еще поддерживаются в GWT), нет способа продолжить обработку, ожидая возврата вызова, если вы используете синхронный метод.