【问题标题】:Synchronous RPC Calls in GWTGWT 中的同步 RPC 调用
【发布时间】:2011-09-08 19:18:57
【问题描述】:

(光是这个标题就应该让人们从木制品中跳出来用棍棒殴打我,但请听我说完)。

我有一个用例,我需要从异步调用中返回一个值。 (我使用的是 GWT-Platform,但概念是相同的。)我声明了一个最终的 JavaScriptObject 数组,然后在 AsyncCallback 中分配了值。但是,我需要返回值,并且该方法在 AsyncCallback 完成之前返回。因此,我需要以某种方式阻止,直到 AsyncCallback 完成。我需要另一个方法中的返回值,或者我只是在 onSuccess() 中做我需要做的事情。

我尝试了循环、计时器和其他一些方法,但都没有成功。有人可以帮忙吗?

@Override
public JavaScriptObject doGetWhereAmIMarker(final double lng, final double lat) {

    final JavaScriptObject[] markerArray = new JavaScriptObject[1];  // ugly hack, I know
    dispatch.execute(new GetLocationDescriptionsAction(lng, lat), new AsyncCallback<GetLocationDescriptionsResult>() {
        @Override
        public void onFailure(Throwable caught) {
            caught.printStackTrace();
        }

        @Override
        public void onSuccess(GetLocationDescriptionsResult result) {
            Map<String, Location> resultMap = result.getResult();
            StringBuffer message = new StringBuffer();
            for (String key : resultMap.keySet()) {
                message.append(key).append(": ").append(resultMap.get(key)).append("\n");
            }

            Map tempMap = new HashMap();
            tempMap.put("TITLE","Location Information");
            tempMap.put("LAT", lat);
            tempMap.put("LNG", lng);
            tempMap.put("CONTENTS", message.toString());

            JavaScriptObject marker = GoogleMapUtil.createMarker(tempMap);
            markerArray[0] = marker;
            if (markerArray[0] != null) {
                GWT.log("Marker Array Updated");
            }

        }
    });

    return markerArray[0];
}

更新:根据要求,这里是调用 doGetWhereIAmMarker() 的代码。我尝试使用 Google Map 对象(作为 JavaScriptObject)作为参数使用单独的本机方法,但似乎在本机方法之间传递该对象会破坏更新所述对象的能力。

public native void initMap(JavaScriptObject mapOptions, JavaScriptObject bounds, JavaScriptObject border, JsArray markerArray, Element e) /*-{

    // create the map and fit it within the given bounds
    map = new $wnd.google.maps.Map(e, mapOptions);
    if (bounds != null) {
        map.fitBounds(bounds);
    }

    // set the polygon for the borders
    if (border != null) {
        border.setMap(map);
    }

    // set up the info windows
    if (markerArray != null && markerArray.length > 0) {
        var infoWindow = new $wnd.google.maps.InfoWindow({
            content:"InfoWindow Content Goes Here"
        });

        for (var i = 0; i < markerArray.length; i++) {
            var marker = markerArray[i];
            marker.setMap(map);
            $wnd.google.maps.event.addListener(marker, 'click', function() {
                infoWindow.setContent(marker.content);
                infoWindow.open(map, this);
            });
        }
    }

    // need to reference the calling class inside the function(), so set a reference to "this"
    var that = this;

   $wnd.whereAmI=function(lng, lat) {
        that.@org.jason.mapmaker.client.view.MapmakerMapViewImpl::whereAmI(DD)(lng,lat);
   }

    $wnd.google.maps.event.addListener(map, 'click', function(event) {
        var lat = event.latLng.lat();
        var lng = event.latLng.lng();
        $wnd.whereAmI(lng, lat);
    });

}-*/;

【问题讨论】:

  • 你能再显示一些代码吗?我对调用此代码的部分以及使用从doGetWhereAmIMarker(...) 返回的 JavaScriptObject 的部分感兴趣。
  • 添加了调用本机方法。 GoogleMapUtil 位于github.com/dartmanx/mapmaker/blob/master/src/main/java/org/…,但未使用 createMarker() 方法提交。但是,它类似于 createMarkerArray() 方法。
  • 如果你只是放一段时间(asyncIsDone){sleep},为什么它不起作用。这似乎是最简单的事情......或者让它成为一个 for(){sleep} ,它会在一段时间后继续?

标签: java gwt jsni


【解决方案1】:

在某些时候,我不得不做一些类似的事情,但最终我删除了那些代码以支持异步的东西。因此,我无法给出您需要使用的确切代码,而只能给出一些关于如何处理它的指示。

  • 首先,this blog 描述了如何使用 javascript 进行同步 AJAX。
  • 其次,您必须为同步调用提供支持。问题是 GWT 不支持提供同步 AJAX 调用的参数。很可能是他们不想鼓励使用它。因此,您需要使用 JSNI 将适当的方法添加到 XMLHttpRequest(您可能会扩展),然后添加到 RequestBuilder(也应该扩展它)。
  • 最后,使用扩展RequestBuilder 修改您的服务。像

((ServiceDefTarget)service).setRpcRequestBuilder(requestBuilder);

总之——来自同一篇博文(有点断章取义):

由于请求丢失和挂起浏览器的危险, 不建议将同步 javascript 用于 (onbefore)卸载事件处理程序。

【讨论】:

  • 我之前做过手动同步 AJAX,但由于这是 GWT,我被 GWT 的限制所困扰。我正在使用 GWT-Platform 的 DispatchAsync 获取数据,但使用 RequestBuilder 没有看到任何内容。
  • 您应该能够通过 JSNI 将任何 Javascript 代码与 GWT 一起使用。 RequestBuilder 在处理 RPC 时在内部使用。获得服务后,您可以使用我提供的 sn-p 分配您的自定义 RequestBuilder
  • 我会接受你的回答,因为它很有趣,可能有一天我需要尝试一下。但是,我找到了阻止我使用异步请求的原始问题的答案。
【解决方案2】:

我认为这都是命运....
我们不能在 Gwt 中捕获响应并发送它,因为在请求发送后立即开始执行下一个方法,既不打扰响应 然而,他们仍然满足我们使用计时器,这就是我的想法......

 Timer t = new Timer() {
      @Override
      public void run() {
        Window.alert("Nifty, eh?");
      }
    };
    t.schedule(5000);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多