回调回调

时间:2011-09-23 08:16:15

标签: javascript asynchronous extjs

我想在地图上放置标记。源是一个json请求,它返回城市。

我有一个函数(sencha)返回记录(异步)和一个函数(google maps api),它返回特定城市的lng,lat(异步)和一个放置标记的方法(google maps)在地图上。

结果应该是谷歌计算出的位置地图上的标记,并从记录中检索到标题。

加载记录

offers = App.stores.offers.load({
    callback: function(records, operation, success){...}
})

获取位置

geocoder = new google.maps.Geocoder();
geocoder.geocode(
  {'address': adress},
  function(results, status) {...}
}

并设置标记

marker = new google.maps.Marker({
  map: map,
  position: loc,
  title: text
});

我不想做的是,加载记录,循环遍历每条记录,找出城市的位置并在那里放置标记。

同步我会这样做:

   records = App.stores.offers.load();
   for (var i=0; i < records.length; i++) {
     setMarker( map, getLocation(records[i].data["city"]), cords[i].data["text"]);
   }

将异步函数与它结合在一起的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

我真的不知道App.stores.offers.load函数究竟做了什么,但我假设它的回调函数参数包含记录变量中的加载结果。在这种情况下,循环遍历回调函数内的记录和每个调用地理编码,以及地理编码的回调位置标记(没有错误)。

编辑:这是未经测试的,可能效率不高但应该有效:

offers = App.stores.offers.load({
    callback: function(records, operation, success){
        if (success) {//or sth like this
            var complete;
            for (var i = 0; i < records.length; i++) {
                complete = false;
                geocoder.geocode( {'address': records[i].adress},
                  function(results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        map.setCenter(results[0].geometry.location);
                        var marker = new google.maps.Marker({
                            map: map,
                            title: results[i].text,
                            position: results[0].geometry.location
                        });
                    } else {
                        alert("Geocode was not successful for the following reason: " + status);
                    }
                    complete = true;
                });
                while (!complete);
            }
        }
    }
});

答案 1 :(得分:0)

最后我用extjs / sencha实现了它。我遇到的第二个问题是谷歌地图服务的限制(我有很多配额超出例外)。所以这不是问题的答案。所以我将另一个答案标记为正确,因为它更接近问题。无论如何,我最终得到的代码可能对某人有帮助。

App.stores.offers = new Ext.data.Store({
 model: 'Offer',
(...)

 listeners: {
  load: function(store, records, success){
  this.addEvents( "refresh_locations", "locations_updated" );
  for (var i=0; i < store.data.length; i++) {
    store.fireEvent("refresh_locations", store , store.getAt(i), "load" );
  }
 },
refresh_locations: function(store, record, method){
  if (record.get("location")  == null || record.get("location") == ""){
    Ext.Ajax.request({
      url: 'api/partner2sport/find_location', 
      params: {
        "city" : record.get("place")
      },
      success: function(response, options) { 
        db_check = Ext.decode(response.responseText)["success"];
        if (db_check){
          var latlngStr = Ext.decode(response.responseText)["location"].replace(/\(|\)/g,"").split(",",2)
          var lat = parseFloat(latlngStr[0]) - (Math.random() / 100);
          var lng = parseFloat(latlngStr[1]) - (Math.random() / 100);
          var latlng = new google.maps.LatLng(lat, lng);
          record.set("location", latlng);
        }else{
          geocoder = new google.maps.Geocoder();
          geocoder.geocode(
            {
                'address': record.get("place")
            },
            function(results, status) {
              if (status == google.maps.GeocoderStatus.OK) {              
                record.set("location", results[0].geometry.location);
                Ext.Ajax.request({
                  url: 'api/partner2sport/set_location', 
                  params: {
                    "city" : record.get("place"),
                    "location": record.get("location")
                  }
                });
              }
            }
          );
        }
      },
      failure: function(response, options) { 
        console.log("bad request");
      }
    });
  }
},

(...)

相关问题