调用回调函数时未定义Google

问题描述 投票:0回答:1
function initMap() {

            var map = new google.maps.Map(document.getElementById('map'), {
              ..........
            var markers = locations.map(function(location, i) {
              return new google.maps.Marker({
                position: location,
                label: labels[i % labels.length]
              });
            });

            // Add a marker clusterer to manage the markers.
            var markerCluster = new MarkerClusterer(map, markers,
                {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
        }


 //Store LatLng of PostalCode
    var locations = [];

function getLatLng(zipcode, callback) 
{
    var geocoder = new google.maps.Geocoder();
    var address = zipcode;
    geocoder.geocode({ 'address': address }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var latitude = results[0].geometry.location.lat();
            var longitude = results[0].geometry.location.lng();
            callback({lat: latitude, lng: longitude });
        } else {
            alert("Request failed.")
        }
    });
}

function getpc(postalcode) {

    getLatLng(postalcode, function (data) {
        locations.push({
            lat : data.lat,
            lng : data.lng
        });
        console.log("lat = " + data.lat + " and lng = " + data.lng);
    });   

}

getpc("640632");

当我试图调用函数getpc()时,它返回谷歌没有定义。但是,如果我试图删除它,则不会发生错误。我搜索了许多方法来解决这个问题但没有一个工作。感谢任何帮助。

这是console.log上显示的错误:

Uncaught ReferenceError: google is not defined
    at getLatLng (GoogleMapTest.aspx:73)
    at getpc (GoogleMapTest.aspx:88)
    at GoogleMapTest.aspx:98
javascript geocoding google-geocoder
1个回答
0
投票

您的ReferenceError(在堆或堆栈中找不到变量)可能是由于您的Google地图api尚未完成您的网页下载和/或解析。

以异步方式加载外部资源有很多好处,但是您所拥有的依赖性问题很常见。

不知道您的最终产品是什么,您有几个选择:

  1. 同步加载maps api,从而确保在调用getpc()时可以可靠地假设google对象将在堆中。将<script src="maps.googleapis.com/maps/api/…" async defer> </script>改为<script src="maps.googleapis.com/maps/api/…"> </script>。 Google文档建议完全删除异步并推迟这些原因

在加载Maps JavaScript API的脚本标记中,可以省略async属性和回调参数。这将导致API的加载被阻止,直到下载API。

这可能会减慢页面加载速度。但这意味着您可以编写后续脚本标记,假设已加载API。

  1. 保持脚本标记中的异步和延迟属性,但不是从您自己的脚本调用getpc,而是在查询参数中将其作为回调参数提供,如下所示:src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=getpc">. If you need to invoke 2 or more functions after the maps api is loaded you could compose these into one
  2. 使用XMLHttpRequest手动下载库,并通过提供XMLHttpRequest.onreadystatechange方法的回调来执行任何后续例程。 MDN handling onreadystatechange
  3. (不推荐)用getpc("640632")替换setTimeout(getpc.bind(null, '640632'), 4000)

更新:听起来你需要这些例程进行排序,以便在getpc之前调用initMap。为此,您可以使用解决方案#3。下面是一个如何工作的例子:

let compose = function(fns) {
  return function() {
    while(fns.length) {
      fns.shift()();
    }
  }
};


let initmap = function() {
  console.log('Init Map');
};


let getpc = function(postalCode) {
  console.log(postalCode);
};


// pass an array of functions you want to be invoked in consecutive order
let initializationRoutines = compose([getpc.bind(null, '123'), initmap]); 

// invoke the functions one-by-one like so
initializationRoutines();

// Instead of invoking initializationRoutines, supply that as the callback to the // maps api. 
// ex: 
<script src="https://maps.googleapis.com/maps/api/jskey=YOUR_API_KEY&callback=initializationRoutines"></script>

最后一点,如果您使用此解决方案,则需要在插入加载地图api的脚本标记之前定义initializationRoutines

<head>
<script>
// Compose and define your functions HERE.... Before you load the map api
let compose = function(fns) {/** ... **/};
let initmap = function() {/** .... **/};
let getpc = function(postalCode) {/** .... **/};

// pass an array of functions you want to be invoked in consecutive order
let initializationRoutines = compose(/** ARRAY_OF_FUNCTIONS**/); 
</script>
<script src="https://maps.googleapis.com/maps/api/jskey=YOUR_API_KEY&callback=initializationRoutines"></script>
</head>
<body>
</body>
© www.soinside.com 2019 - 2024. All rights reserved.