2012-06-23 4 views
3

У меня есть метод в GWT, который извлекает данные из БД с использованием метода пожара запросов, так как вы все знаете его асинхронный. Я вызываю этот метод из JS, поэтому мне нужно сделать синхронный, это возможноGWT Синхронный вызов

private static String retriveLocation(String part) 
{ 
    ClientFactory clientFactory = GWT.create(ClientFactory.class); 
    MyRequestFactory requestFactory = clientFactory.getRequestFactory(); 
    YadgetRequest request = requestFactory.yadgetRequest(); 
    String criteria = "!" + part; 
    final ArrayList<String> tags = new ArrayList<String>(); 

    request.getTagsStartingWith(criteria, 10, 0).fire(
      new Receiver<List<TagProxy>>() { 
       @Override 
       public void onSuccess(List<TagProxy> tagList) { 
        String output = "["; 

        for (TagProxy pt : tagList) { 
         output += "{"; 
         output += "\"id\":" + "\"" + pt.getId() + "\","; 
         output += "\"value\":" 
           + "\"" 
           + pt.getName().replaceAll("\"", "") 
             .replaceAll("!", "") + "\""; 
         output += "},"; 

        } 
        if (output.length() > 2) 
         output = output.substring(0, output.length() - 1); 
        output += "]"; 
        tags.add(output); 

       } 

       @Override 
       public void onFailure(ServerFailure error) { 

       } 

      }); 

    return tags.size() + ""; 

} 

и вызова этой функции от JS вроде этого:

public static native void exportStaticMethod() /*-{ 
    $wnd.computeLoanInterest = 
    $wnd.getAutocomplete [email protected]::retriveLocation(Ljava/lang/String;); 
}-*/; 

и внутри onModuleLoad() я называю exportStaticMethod().

и в HTML У меня есть кнопка, я называю OnClick getAutocomplete() так:

<input type="button" onclick="alert(getAutocomplete('j'))" value="momo" /> 

Проблема заключается в том, что размер всегда возвращает 0, так как метод асинхронно, но если бы я мог вернуть значение onSuccess, что бы решить моя проблема. Любые идеи, пожалуйста? Я уже 2 дня искал его и не получил ответа.

Другими словами:

У меня есть метод JS Мне нужно вызвать метод Java для извлечения данных из БД, но синхронно!

Пример

Если у меня есть кнопка HTML и нажмите пройду идентификатор функции и мне нужно retrive имя из БД с помощью GWT и предупредить его; просто потому, что GWT является асинхронным, я не буду в состоянии делать это каждый раз, и когда я предупреждаю результат, он будет пустым, потому что он еще не заполнен.

+0

RPC-вызов - это асинхронный вызов, поэтому он попытается вернуть tag.size до того, как вызов rpc не будет завершен. так что это неверно логически. поместите sysout для tags.size в успех и удалите оператор return. Сделайте код внутри успеха, если вам нужна подробная информация о тегах. – iMBMT

+0

@Bhumika I c, но, как вы видите в моем [ost, я называю это функцией javascript и значением, которое должно быть exisit, когда я вызываю его из javascript, поэтому мне нужно добавить возвращаемое значение, есть ли какая-нибудь работа вокруг? –

+0

Таким образом, вы не можете получить правильный список тегов в return statement.but, см. Jsni. создайте другой метод, который вызовет java для javascript. назовите его успешным после установки списка тегов. это будет работать. – iMBMT

ответ

6

Вы не можете использовать собственный GWT RPC синхронно. Я не уверен, что это то, что вы просите, но вот как сделать вызов на сервер синхронно:

private native String makeSyncAjaxCall(String url, String msgText, String conType)/*-{ 
    var xhReq = new XMLHttpRequest(); 
    xhReq.open(conType, url, false); 
    if(conType == "POST") xhReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded'); 
    xhReq.send(msgText); 
    var serverResponse = xhReq.status + xhReq.responseText; 
    return serverResponse; 
}-*/; 

Пожалуйста, обратите внимание, что я не обсуждаю ли это хорошая идея или нет. Вероятно, вы должны придерживаться Async и поставить предупреждение на событие успеха.

+0

благодарю вас за помощь! но мне нужно, чтобы работа GWT RPC была синхронной, любая работа может быть, если есть какая-либо функция задержки или ожидания, которая может помочь? –

+0

AFAIK, вы не можете. Многие люди пытались эмулировать синхронизацию, используя такие идеи ... но Javascript действительно однопоточный, поэтому обратный вызов даже не будет выполняться до тех пор, пока задержка не закончится. – AhHatem

+0

GWT RPC явно предназначен для предотвращения этого :), поэтому вы не можете использовать его, если вы, конечно, не модифицируете источник. – AhHatem

3

GWT не позволяет делать синхронные вызовы на сервер, так как они могут заставить ваш браузер зависать, пока он не получит ответ, поэтому по очевидным причинам лучше всего изменить поток, чтобы результат с сервера обрабатываться внутри обработчика событий onSuccess.

мой бизнес нужно, чтобы сделать функцию JS извлечения данных из БДА, но он должен быть SYNCHRONOUS

Вы можете получить данные из базы данных только с помощью Java (или с помощью любого другого серверного языка) , но не используя JavaScript. Просто сделайте асинхронный вызов от GWT, используя либо RequestBuilder, либо механизм GWT RPC. Как уже упоминалось, возвращаемые данные могут быть обработкой внутри соответствующих обработчиков.

+0

Я знаю манику, поэтому я использую JSNI для извлечения данных, но мне это нужно синхронно, асинхронно! –

+0

Используйте тег скрипта и вставляйте его во время вызова javascript ... Это должно заморозить для вас окно;) – Ajax

3

Ахмад, ссылаясь на пример вы цитируемый:

вызвать функцию Click, скажем «getNamefromID()» в GWT, что делает асинхронный вызов к БД и в функции OnSuccess(), называют функцию, которая будет предупреждать имя.

public void getNamefromID(int ID) { 
    String postUrl = "http://mani/getName"; 
    String requestData = "q=ID"; 
    RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, 
      postUrl); 
    builder.setHeader("Access-Control-Allow-Origin", "*"); 
    try { 
     builder.sendRequest(requestData.toString(), new RequestCallback() { 
      public void onError(Request request, Throwable e) { 
       Window.alert(e.getMessage()); 
      } 

      public void onResponseReceived(Request request, 
        Response response) { 
       if (200 == response.getStatusCode()) { 
        Window.alert("Name :" + response.getText()); 
       } else { 
        Window.alert("Received HTTP status code other than 200 : " 
          + response.getStatusText() 
          + "Status Code :" 
          + response.getStatusCode()); 
       } 
      } 
     }); 
    } catch (RequestException e) { 
     // Couldn't connect to server 
     Window.alert(e.getMessage()); 
    } 
} 
1

От https://stackoverflow.com/a/40610733/6017801:

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

private static native void fakeXMLHttpRequestOpen() /*-{ 
    var proxied = $wnd.XMLHttpRequest.prototype.open; 

    (function() { 
     $wnd.XMLHttpRequest.prototype.open = 
      function() { 
       arguments[2] = false; 
       return proxied.apply(this, [].slice.call(arguments)); 
      }; 
     })(); 
}-*/; 

После вызова fakeXMLHttpRequestOpen(), любое дальнейшее использование XMLHttpRequest будет действовать синхронно. Например:

remoteSvc.getResult(new AsyncCallback<String>() { 
    @Override 
    public void onSuccess(String result) { 
     GWT.log("Service called!"); 
    } 

    @Override 
    public void onFailure(Throwable caught) { 
     GWT.log("Service failed..."); 
    } 
} 

GWT.log("Last message"); 

будет оказывать ВСЕГДА:

Service called! 
Last message 

См https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open для XMLHttpRequest.open() спецификации.

Смежные вопросы