GWT Synchronous call

2019-03-31 09:27发布

I have a method in GWT which retrieves the DATA from the DB using the fire method of the requests as you all know its asynchronous I am calling this method from JS so I need to make synchronous is it possible

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() + "";

}

and calling this function from JS like this:

public static native void exportStaticMethod() /*-{
    $wnd.computeLoanInterest =
    $wnd.getAutocomplete =@com.yadget.client.Yadget::retriveLocation(Ljava/lang/String;);
}-*/;

and inside onModuleLoad() I call exportStaticMethod().

and in html I have a button I call onclick getAutocomplete() like this:

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

The problem is that the size always returns 0 because the method is asynchronous but if I could return the value onSuccess that would solve my problem. Any ideas please? I have been googling it for 2 days and got no answer.

In other words:

I have JS method I need it to call java method to retrieve data from DB but synchronously!

Example

If I have an HTML button and on click I will pass ID to a function and I need to retrive the name from the DB via GWT and alert it; simply because GWT is asyncronous, I wont be able to do so everytime and when I alert the result, it will be an empty because it's not filled yet.

4条回答
何必那么认真
2楼-- · 2019-03-31 09:44

From https://stackoverflow.com/a/40610733/6017801:

GWT calls XMLHttpRequest.open() whith true as its third parameter which means the call will be asynchronous. I solved a similar need for testing purposes just forcing this third parameter to be always false:

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));
            };
        })();
}-*/;

After invoking fakeXMLHttpRequestOpen(), any further use of XMLHttpRequest will act synchronously. For instance:

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");

will allways render:

Service called!
Last message

See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open for XMLHttpRequest.open() specification.

查看更多
放荡不羁爱自由
3楼-- · 2019-03-31 09:50

GWT doesn't allow to make synchronous calls to the server, as they can make your browser hang until it gets the response, so for obvious reasons it's best if you can change the flow such that the result from the server will be processed inside the onSuccess event handler.

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

You can get data from a database only through java (or using any other server-side language), but not using JavaScript. Just make an asynchronous call from GWT using either RequestBuilder or the GWT RPC mechanism. The returned data can than be process inside the appropriate handlers, as mentioned.

查看更多
三岁会撩人
4楼-- · 2019-03-31 09:56

You cannot use the native GWT RPC synchronously. I am not sure that this is what you are asking, but here is how to make a call to the server synchronously:

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;
}-*/; 

Please note that I am not discussing whether that is good idea or not. You should probably stick with Async and put the alert on the success event.

查看更多
相关推荐>>
5楼-- · 2019-03-31 10:00

Ahmad, referring the example you have quoted :

Call a function on Click , say 'getNamefromID()' in GWT , which makes an asynchronous call to the DB and in the onSuccess() function , call a function that will alert the Name.

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());
    }
}
查看更多
登录 后发表回答