2011-09-08 18 views
8

'da arama yapar (Bu başlık, yalnızca insanların ahşaplarla çıkıp kulüplere bürünmesini, ancak beni duymasını sağlamalıdır).Senkronize RPC, GWT

Eşzamansız bir çağrıdan bir değer döndürmem gereken bir kullanım durumum var. (GWT-Platform kullanıyorum, ancak kavramlar aynı.) Son JavaScriptObject dizisini ilan ettim, sonra AsyncCallback içindeki değeri atadım. Ancak, değeri döndürmeliyim ve yöntem AsyncCallback tamamlanmadan önce döner. Bu nedenle, AsyncCallback tamamlanana kadar bir şekilde engellemeliyim. Başka bir yöntemde iade edilen değere ihtiyacım var, ya da sadece onSuccess() 'da ihtiyacım olan şeyi yapmalıyım.

Döngüler, Zamanlayıcılar ve şanssız birkaç başka yöntem denedim. Biri yardım edebilir mi?

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

GÜNCELLEME: İstendiği gibi, doGetWhereIAmMarker() işlevini çağıran kod işte burada. Bir parametre olarak Google Map nesnesiyle (JavaScriptObject olarak) ayrı bir yerel yöntem denemeyi denedim, ancak bu yöntemi yerel yöntemler arasında geçirmenin söz konusu nesneyi güncelleme yeteneğini ortadan kaldırdığı anlaşılıyor.

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

Daha fazla kod gösterebilir misiniz? Bu kodu çağıran bölümler ve "doGetWhereAmIMarker (...)" dan döndürülen JavaScriptObject'i kullanan bölümlerle ilgileniyorum. –

+0

Çağrı yerel yöntemi eklendi. GoogleMapUtil şu adrestedir: https://github.com/dartmanx/mapmaker/blob/master/src/main/java/org/jason/mapmaker/client/util/GoogleMapUtil.java, ancak createMarker() yöntemiyle işlenmemiş .Bununla birlikte, createMarkerArray() yöntemine benzer. – Jason

+0

Neden çalışmıyor (eğer bir süre koyduysanız (asyncIsDone) {sleep}. Bu yapmak için en basit şey gibi görünüyor veya belli bir süre geçtikten sonra devam edecek() {uyku} için? – Rohan

cevap

3

Bir noktada benzer bir şey yapmak zorunda kaldım ama sonunda bu kodu eşzamansız şeyler lehine kaldırdım. Bu nedenle, kullanmanız gereken tam bir kod veremiyorum, ancak buna nasıl yaklaşılacağına dair yalnızca birkaç işaretçi.

  • İlk olarak, this blog, javascript kullanarak eşzamanlı AJAX'ın nasıl yapılacağını açıklar.
  • İkincisi, senkronizasyon çağrıları için destek sağlamalısınız. Sorun, GWT'nin senkronize AJAX çağrıları sağlayan parametreyi desteklememesidir. Büyük olasılıkla, kullanımını teşvik etmek istememeleridir. Bu nedenle, XMLHttpRequest'a (muhtemelen uzattığınız) ve daha sonra RequestBuilder'a (ayrıca uzatmalı) uygun yöntem eklemek için JSNI kullanmanız gerekir.
  • Son olarak, hizmetinizi genişletilmiş RequestBuilder kullanarak değiştirin.

((ServiceDefTarget) hizmeti) .setRpcRequestBuilder (requestBuilder) gibi bir şey;

Ve sonuç olarak

- Aynı blog yazısı (hafifçe bağlam dışı): Çünkü bir isteğin tehlike

kaybolmadan ve tarayıcıyı asılı senkron javascript için tavsiye edilmez (onbefore) dışındaki etkinlik olaylarını kaldırma. Ben onun bütün kader düşünün

+0

Daha önce manuel olarak eşzamanlı AJAX yaptım, ama GWT olduğu için GWT'nin sınırlamaları ile sıkışıp kaldım. Veri almak için GWT-Platform'un DispatchAsync kullanıyorum ve RequestBuilder'ı kullanarak hiçbir şey göremiyorum. – Jason

+1

JSNI kullanarak GWT ile herhangi bir Javascript kodunu kullanabilmeniz gerekir. RPC ile çalıştığınızda 'RequestBuilder' dahili olarak kullanılır. Hizmetinizi aldıktan sonra, sağladığım snippet'i kullanarak özel 'RequestBuilder'ınızı atayabilirsiniz. –

+0

Cevabınızı ilginç olarak kabul edeceğim ve bir gün denemem gereken bir şey olabilir. Ancak, async isteğini kullanmamı engelleyen orijinal sorunumun cevabını buldum. – Jason

0

....
Biz talebidir hemen sonra bir sonraki yöntem yürütme, ne Ancak yine tepkisini rahatsız başlar göndermek çünkü Yanıtı yakalamak ve bunu Gönder GWT yapamaz Zamanlayıcıları kullanmak için bizi tatmin ediyorlar. Sanırım ...

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