【问题标题】:GWT Synchronous callGWT 同步调用
【发布时间】:2012-06-23 04:48:59
【问题描述】:

我在 GWT 中有一个方法,它使用请求的 fire 方法从数据库中检索 DATA,因为你们都知道它是异步的

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 中我有一个按钮,我像这样调用 onclick getAutocomplete()

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

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

换句话说:

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

例子

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

【问题讨论】:

  • RPC 调用是异步调用,因此即使 rpc 调用未完成,它也会尝试返回 tags.size。所以在逻辑上是不正确的。将tags.size的sysout成功并删除return语句。如果您必须要求标签列表详细信息,请在成功内编写代码。
  • @Bhumika I c 但正如你在我的 [ost 我从 javascript 函数调用它并且当我从 javascript 调用它时存在的值所以我必须输入返回值有没有解决方法?
  • 这样你不能在return statement.but中得到正确的标签列表。但是参考jsni。创建另一个将调用 java 到 javascript 的方法。设置标签列表后调用它成功。这将有效。
  • @Bhumika 真的很感谢你的建议,但它仍然不能帮助我完成我的工作!我的业务需要是让 JS 函数从数据库中检索数据,但它必须是同步的

标签: gwt asynchronous sync synchronous jsni


【解决方案1】:

您不能同步使用本机 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 被明确设计为防止这种情况:) 所以你不能使用它,除非你当然修改源代码。
【解决方案2】:

GWT 不允许对服务器进行同步调用,因为它们可以让您的浏览器在收到响应之前挂起,因此出于显而易见的原因,最好您可以更改流程以使来自服务器的结果为在onSuccess 事件处理程序中处理。

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

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

【讨论】:

  • 我知道 manika 这就是我使用 JSNI 检索数据但我需要它同步而不是异步的原因!
  • 使用脚本标签,并在 javascript 调用期间嵌入它...这应该会为您冻结窗口;)
【解决方案3】:

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

在 Click 上调用一个函数,比如 GWT 中的“getNamefromID()”,这会对 DB 进行异步调用,在 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());
    }
}

【讨论】:

    【解决方案4】:

    来自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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多