【问题标题】:Can't wait unitil results come back from google API不能等到结果从谷歌 API 返回
【发布时间】:2013-07-24 14:00:18
【问题描述】:

我有两个函数:getCoordinate()和getDistance(),都需要向google apis发起异步请求,结果是一个json文件,

获取距离:

function getDistance(origin,destination,mode)
{
var url="http://maps.googleapis.com/maps/api/distancematrix/json?";

var origin="origins="+origin;
var destination="&destinations="+destination;
var mode="&mode="+mode;
var language="&language=fr-FR"
var sensor="&sensor=false";

var def = new jQuery.Deferred(); 
var city;
$.getJSON(url+origin+destination+mode+language+sensor,function(json)
{
    if (json.status=="OK")
    {
    var distance=json.rows[0].elements[0].distance.value;
    }
    def.resolve(distance);
});
return def.promise();
}

这是getCoordinates:

function getCoordinate(address)
{

var url="http://maps.googleapis.com/maps/api/geocode/json?address=";
var sensor="&sensor=false";
var def = new jQuery.Deferred(); 
var city;
$.getJSON(url+address+sensor,function(json)
{
    var lat=json.results[0].geometry.location.lat;
    var lng=json.results[0].geometry.location.lng;
    var dist=google.maps.geometry.spherical.computeDistanceBetween(myCenter,new google.maps.LatLng(lat,lng));
    console.log('address:'+dist/1000+'km');                                                    
    var coord=[lat,lng];
    def.resolve(coord);

});
return def.promise();
}

我需要在getDistance()中使用getCoordinate()方法的结果, 但由于异步模式 getDistance 指令在结果从谷歌返回之前执行。

   for (i=0;i<addresses.length;i++)
{
$.when(getCoordinate(addresses[i])).then(function (coord) {
var myLatitude=coord[0];
var myLongitude=coord[1];
addressList[j++]=[coord[0],coord[1]];
    $.when(getDistance(lat+","+lng,myLatitude+","+myLongitude,"driving")).then(function(distance)
    {
    var test=i;
    var distTab=[];
    switch(i){
        case 0:
        //do Something
        break;

        default:
        //do something
        break;
          }
        }
    });

});
}       console.log("the dist:"+distance);
    console.log("coordinate:"+myLatitude+","+myLongitude);
    console.log("Center:"+lat+","+lng);

【问题讨论】:

  • console.log("the dist:"+distance); 为每次迭代返回不同的值,但 console.log("coordinate:"+myLatitude+","+myLongitude); 始终给出相同的结果。而i = 4 女巫是addresses的长度
  • 为什么不让距离矩阵进行地理编码?您不必传递坐标,您可以使用地址。
  • 您可以使用 jQuery .when().then() 方法来控制异步调用。

标签: jquery ajax google-maps-api-3


【解决方案1】:

由于您已经在使用“google.maps”,因此将所有 lat/lng 值作为“google.maps.LatLng”对象传递是有好处的。

此外,变量仅在作用域内且仅在异步回调中分配一次时才可寻址,因此您对console.log() 的某些尝试注定会失败。

应用这些原则并(显着)整理,我得到:

function getDistance(origin, destination, mode) {
    //Note: //origin, destination are now google.maps.LatLng objects
    var url = "http://maps.googleapis.com/maps/api/distancematrix/json";
    var data = {
        origin: origin.toUrlValue(),
        destination: destination.toUrlValue(),
        mode: mode,
        language: "fr-FR",
        sensor: "false"
    };
    return $.getJSON(url, data).then(function(json) {
        if(json.status=="OK") {
            return json.rows[0].elements[0].distance.value;
        }
        else return $.Deferred().reject().promise();
    });
}

function getCoordinate(address) {
    var url="http://maps.googleapis.com/maps/api/geocode/json";
    var data = {
        address: address,
        sensor: "false"
    };
    return $.getJSON(url, data).then(function(json) {
        if(json.results && json.results.length && json.results[0].geometry) {
            var latLng = new google.maps.LatLng(
                json.results[0].geometry.location.lat,
                json.results[0].geometry.location.lng
            );
            console.log("Center: " + latLng.toString());
            return latLng;
        }
    });
}

for (i=0; i<addresses.length; i++) {
    getCoordinate(addresses[i]).then(function(latLng) {
        console.log("coordinate: " + latLng.toString());
        addressList[j++] = latLng;//now a google.maps.LatLng object
        getDistance(myOrigin, latLng, "driving").then(function(distance) {
            console.log("the dist:" + distance);
            switch(i) {
                case 0: /* do Something */ break;
                default: /* do something */ break;
            }
        });
    });
}

未经测试

当然,这不会直接开箱即用,因为您的其余代码将需要适应 google.maps.LatLng 对象,特别是我称为 myOrigin 的变量(以前为 latlng 在某些外部范围内)和addressList 中的那些。

【讨论】:

  • 答案很好,你必须花一些时间,我还没试过,但我有一个问题,我能得到addressListgetDistance(myOrigin, latLng, "driving").then(function(distance) {here}
  • 如果我理解正确,那么是的。如果addressList 在表达式addressList[j++] ... 的范围内,那么它将在.then() 回调中自动访问,这是同一范围的内部函数。该规则是 javascript 固有的。使addressList 在内部范围内无法访问的唯一方法是在该内部范围内定义一个“私有”var addressList
  • 在收到 Json 响应之前,i 会从 0 变为 addresses.length
  • 是的,正如所写,您所描述的行为是绝对有保证的,但是getCoordinate() ... getDistance() ... 的请求序列将针对每个address 独立发生。如果您希望一次只处理一个请求序列(即,如果您希望每个 address 等待前一个 address 完成),那么这是一个不属于问题的附加问题。跨度>
  • 不用担心 Hossam。祝你好运。
【解决方案2】:

第一个函数成功调用第二个函数

var getCoordinate() { //call initial function
   $.ajax({
        success: function(results) {
            getDistance(results);//call second function with the results of the first call
        }
   });
};

【讨论】:

  • 我还需要 Deferred 对象吗?
  • 我不明白,你能把你的函数命名为矿井更清楚吗
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 2012-07-06
  • 1970-01-01
相关资源
最近更新 更多