3

我在 GWT 中有一个方法,它使用请求的 fire 方法从数据库中检索数据,因为你们都知道它是异步的,我从 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()像这样调用 onclick:

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

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

换句话说:

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

例子

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

4

4 回答 4

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 并将警报放在成功事件上。

于 2012-06-23T10:17:46.350 回答
3

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

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

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

于 2012-06-23T10:19:12.560 回答
3

艾哈迈德,指的是你引用的例子:

在 Click 上调用一个函数,例如 GWT 中的“getNamefromID()”,它对 DB 进行异步调用,在 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());
    }
}
于 2012-06-23T11:53:24.857 回答
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

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

于 2016-11-15T13:16:59.553 回答