2011-09-08 69 views
8

(Tiêu đề đó một mình sẽ khiến mọi người thoát ra khỏi đồ gỗ để bash tôi với câu lạc bộ, nhưng nghe tôi nói).Cuộc gọi RPC Đồng bộ trong GWT

Tôi có trường hợp sử dụng mà tôi cần trả lại giá trị từ cuộc gọi không đồng bộ. (Tôi đang sử dụng GWT-Platform, nhưng các khái niệm đều giống nhau.) Tôi đã khai báo một mảng JavaScriptObject cuối cùng, sau đó gán giá trị trong AsyncCallback. Tuy nhiên, tôi cần trả về giá trị và phương thức trả về trước khi AsyncCallback hoàn tất. Vì vậy, tôi cần phải chặn bằng cách nào đó cho đến khi AsyncCallback hoàn thành. Tôi cần giá trị trả về trong một phương thức khác, hoặc tôi chỉ cần làm những gì tôi cần trong onSuccess().

Tôi đã thử vòng lặp, Bộ hẹn giờ và một vài phương pháp khác không có may mắn. Có ai giúp được không?

@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]; 
} 

Cập nhật: Theo yêu cầu, đây là mã gọi doGetWhereIAmMarker(). Tôi đã cố gắng có một phương pháp riêng biệt riêng với đối tượng Google Map (dưới dạng JavaScriptObject) làm tham số, nhưng dường như việc truyền đối tượng đó giữa các phương thức gốc sẽ làm mất khả năng cập nhật đối tượng đã nói.

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) { 
     [email protected]::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); 
    }); 

}-*/; 
+0

Bạn có thể hiển thị thêm một số mã không? Tôi quan tâm đến các phần gọi mã này, và cũng là các phần tiêu thụ JavaScriptObject được trả về từ 'doGetWhereAmIMarker (...)'. –

+0

Đã thêm phương thức gốc gọi. GoogleMapUtil có tại https://github.com/dartmanx/mapmaker/blob/master/src/main/java/org/jason/mapmaker/client/util/GoogleMapUtil.java, nhưng không được cam kết với phương thức createMarker() .Nó tương tự như phương thức createMarkerArray(). – Jason

+0

Tại sao nó không hoạt động sau đó nếu bạn chỉ cần đặt một thời gian (asyncIsDone) {sleep}. có vẻ như điều đơn giản nhất để làm ... hoặc biến nó thành() {sleep} sẽ tiếp tục sau một thời gian nhất định? – Rohan

Trả lời

3

Tại một thời điểm nào đó, tôi phải làm điều gì đó tương tự nhưng cuối cùng tôi đã xóa mã đó để ủng hộ nội dung không đồng bộ. Do đó, tôi không thể cung cấp mã chính xác mà bạn cần sử dụng nhưng chỉ có một vài gợi ý về cách tiếp cận nó.

  • Trước tiên, this blog mô tả cách thực hiện AJAX đồng bộ bằng javascript.
  • Thứ hai, bạn phải cung cấp hỗ trợ cho các cuộc gọi đồng bộ hóa. Vấn đề là GWT không hỗ trợ tham số cung cấp các cuộc gọi AJAX đồng bộ. Nhiều khả năng là họ không muốn khuyến khích việc sử dụng nó. Vì vậy, bạn sẽ cần phải sử dụng JSNI để thêm phương thức thích hợp vào XMLHttpRequest (mà bạn có thể sẽ mở rộng) và sau đó đến RequestBuilder (cũng nên mở rộng nó).
  • Cuối cùng, sửa đổi dịch vụ của bạn bằng cách sử dụng mở rộng RequestBuilder. Một cái gì đó như

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

Và trong kết luận - từ bài viết trên blog cùng (hơi ra khỏi ngữ cảnh):

Bởi vì sự nguy hiểm của một yêu cầu bị mất và treo trình duyệt, javascript đồng bộ không được khuyến khích cho bất cứ điều gì bên ngoài của (onbefore) dỡ bỏ xử lý sự kiện.

+0

Tôi đã thực hiện AJAX đồng bộ thủ công trước đây, nhưng vì đây là GWT, tôi bị kẹt với các hạn chế của GWT. Tôi đang sử dụng DispatchAsync của GWT-Platform để nhận dữ liệu và tôi không thấy bất kỳ thứ gì trong đó bằng cách sử dụng RequestBuilder. – Jason

+1

Bạn sẽ có thể sử dụng bất kỳ mã Javascript nào với GWT bằng cách sử dụng JSNI. 'RequestBuilder' được sử dụng trong nội bộ khi bạn xử lý RPC. Khi bạn có dịch vụ của mình, bạn có thể gán tùy chọn 'RequestBuilder' bằng đoạn mã mà tôi đã cung cấp. –

+0

Tôi sẽ chấp nhận câu trả lời của bạn vì nó thú vị và có thể là điều tôi cần thử một ngày nào đó. Tuy nhiên, tôi đã tìm thấy câu trả lời cho vấn đề ban đầu đã ngăn tôi sử dụng yêu cầu không đồng bộ. – Jason

0

Tôi nghĩ nó tất cả số phận ....
Chúng tôi không thể làm trong Gwt để bắt phản ứng và gửi nó, bởi vì ngay sau khi yêu cầu là gửi các phương pháp tiếp theo bắt đầu thực hiện, không phải làm phiền các phản ứng Tuy nhiên tuy nhiên họ thỏa mãn chúng tôi để sử dụng Bộ hẹn giờ, là những gì tôi nghĩ ...

Timer t = new Timer() { 
     @Override 
     public void run() { 
     Window.alert("Nifty, eh?"); 
     } 
    }; 
    t.schedule(5000); 
Các vấn đề liên quan