Вопрос по sync, synchronous, asynchronous, gwt, jsni – GWT Синхронный звонок

3

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

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 у меня есть кнопка, которую я вызываю onclickgetAutocomplete() как это:

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

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

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

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

пример

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

@Bhumika действительно спасибо за ваши предложения, но тем не менее это не поможет мне в достижении моей работы! моя бизнес-задача - заставить функцию JS извлекать данные из БД, но ЭТО ДОЛЖНО БЫТЬ СИНХРОННО John Donvan
Вызов RPC является асинхронным, поэтому он попытается вернуть tags.size, даже если вызов rpc не завершен. так что это не правильно по логике. успешно запустите sysout для tags.size и удалите оператор return. Делайте код внутри успеха, если вам нужны подробности списка тегов. bNd
@Bhumika, но я, как вы видите в моем [ost, я вызываю это из функции javascript и значением, которое должно быть exisit, когда я вызываю его из javascript, поэтому я должен вставить возвращаемое значение, есть ли обходной путь? John Donvan
Таким образом, вы не сможете получить правильный список тегов в возвращаемом операторе. Но обратитесь к jsni. создать другой метод, который будет вызывать Java для JavaScript. назовите это на успех после установки списка тегов. это будет работать. bNd

Ваш Ответ

4   ответа
3

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

Вызовите функцию при нажатии, скажем, «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());
    }
}
3

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

my business need is to make a JS function retrieve data from DB but IT MUST BE SYNCHRONOUS

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

Я знаю manika, поэтому я использую JSNI для извлечения данных, но мне нужно, чтобы это было синхронно, а не асинхронно! John Donvan
Используйте тег script и вставьте его во время вызова javascript ... Это должно заморозить окно для вас;)
1

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

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

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 ().

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 и поставить предупреждение на событие успеха.

GWT RPC явно разработан для предотвращения этого :), поэтому вы не можете использовать его, если, конечно, не измените источник.
AFAIK, ты не можешь. Многие люди пытались эмулировать синхронизацию, используя подобные идеи ... но Javascript действительно однопоточный, поэтому обратный вызов даже не будет выполнен, пока не закончится задержка.
Спасибо за помощь ! но мне нужно, чтобы GWT RPC работал синхронно, может ли быть любой обходной путь, если есть какая-либо функция задержки или ожидания, которая может помочь? John Donvan

Похожие вопросы