【问题标题】:Google is not defined when callback function called调用回调函数时未定义 Google
【发布时间】:2019-03-22 02:32:42
【问题描述】:
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() 时,它返回 google 未定义。但是,如果我尝试删除它,则不会发生错误。我搜索了很多方法来解决这个问题,但没有一个奏效。感谢任何帮助。

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

Uncaught ReferenceError: google is not defined
    at getLatLng (GoogleMapTest.aspx:73)
    at getpc (GoogleMapTest.aspx:88)
    at GoogleMapTest.aspx:98

【问题讨论】:

  • @brian-lives-outdoors 是的,我在

标签: javascript geocoding google-geocoder


【解决方案1】:

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

异步加载外部资源有很多好处,但是像您遇到的那样的依赖问题很常见。

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

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

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

这可能会减慢您的页面加载速度。但这意味着您可以在 API 已经加载的情况下编写后续脚本标签。

  1. 在脚本标记中保留 async 和 defer 属性,但不要从您自己的脚本中调用 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)

更新: 听起来您需要对这些例程进行排序,以便在initMap 之前调用getpc。为此,您可以使用解决方案#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>

【讨论】:

  • 谢谢。我还面临一个问题,即尽管使用了回调,但 lat 和 lng 并没有被推送到这些位置。
  • 我使用了console.log,发现在getpc()执行完成之前,地图已经加载完毕。如何在 initmap() 之前执行 getpc()?
  • 或者我还有什么其他办法吗?
猜你喜欢
  • 1970-01-01
  • 2012-02-23
  • 2021-08-11
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2015-07-02
  • 1970-01-01
相关资源
最近更新 更多