GWT同步通话

时间:2012-06-23 04:48:59

标签: gwt asynchronous sync synchronous jsni

我在GWT中有一个方法,它使用请求的fire方法从数据库中检索DATA,因为你们都知道它的异步我从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 =@com.yadget.client.Yadget::retriveLocation(Ljava/lang/String;);
}-*/;

onModuleLoad()内,我致电exportStaticMethod()

在html中我有一个按钮,我点击getAutocomplete()就像这样:

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

问题是大小总是返回0,因为该方法是异步的,但是如果我可以返回值onSuccess来解决我的问题。有什么想法吗?我已经谷歌搜索了2天而没有得到答案。

换句话说:

我有JS方法我需要它来调用java方法来从DB中检索数据但同步!

实施例

如果我有一个HTML按钮并且单击,我会将ID传递给一个函数,我需要通过GWT从数据库中检索该名称并提醒它;仅仅因为GWT是异步的,我不能每次都这样做,当我提醒结果时,它会是空的,因为它还没有被填充。

4 个答案:

答案 0 :(得分: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并将警报置于成功事件上。

答案 1 :(得分:3)

GWT不允许对服务器进行同步调用,因为它们可以使浏览器挂起直到获得响应,因此出于显而易见的原因,如果您可以更改流量以使服务器的结果为在onSuccess事件处理程序内处理。

  

我的业务需求是让JS函数从数据库中检索数据,但它必须是同步的

您只能通过java(或使用任何其他服务器端语言)从数据库获取数据,但不能使用JavaScript。只需使用RequestBuilder或GWT RPC机制从GWT进行异步调用。如上所述,返回的数据可以在适当的处理程序内处理。

答案 2 :(得分:3)

艾哈迈德,参考你引用的例子:

在Click上调用一个函数,在GWT中调用'getNamefromID()',这对数据库进行异步调用,在onSuccess()函数中,调用一个将警告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());
    }
}

答案 3 :(得分:1)

来自https://stackoverflow.com/a/40610733/6017801

GWT调用 XMLHttpRequest.open() whith为第三个参数,这意味着调用将是异步的。我解决了类似的测试需求,只是强迫第三个参数始终为false:

 A = LOAD '/path/to/file' USING PigStorage(';') AS(col1,col2...);

 Dumping given column with name. 
 B =foreach A generate col1;
 dump B

在调用 fakeXMLHttpRequestOpen()之后,XMLHttpRequest的任何进一步使用将同步执行。例如:

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

总是呈现:

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

有关XMLHttpRequest.open()规范,请参阅https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open