Ваша ошибка ReferenceError (переменная не найдена в куче или в стеке), скорее всего, из-за того, что API-интерфейс ваших карт Google еще не завершил загрузку и / или не проанализировал вашу веб-страницу.
Существует множество преимуществ загрузкивнешние ресурсы асинхронно, однако проблемы с зависимостями, такие как у вас, являются общими.
Не зная, каков ваш конечный продукт, у вас есть несколько вариантов:
- Синхронно загрузить API-карты, таким образом, гарантируя, что при вызове
getpc()
вы можете с уверенностью предполагать, что объект google
будет в куче.Измените <script src="maps.googleapis.com/maps/api/…" async defer> </script>
на <script src="maps.googleapis.com/maps/api/…"> </script>
.Документы Google предлагают удалить async и defer по этим причинам точно
В теге script, который загружает JavaScript API Карт, можно пропустить атрибут async и параметр callback.Это приведет к блокировке загрузки API, пока API не будет загружен.
Это, вероятно, замедлит загрузку вашей страницы.Но это означает, что вы можете написать последующие теги сценария, предполагая, что API уже загружен.
Сохраните асинхронные и отложенные атрибуты в теге сценария, но вместо вызова 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
Вручную загрузите библиотеку, используя XMLHttpRequest
, и выполните любые последующие процедуры, передав обратный вызов методу XMLHttpRequest.onreadystatechange
. Работа с MDN при изменении состояния
(не рекомендуется) заменить 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>
Последнее замечание: если вы используете это решение, вам нужно будет определить initializationRoutines
перед тем, как вставить тег сценария, который загружает API-карты, например, так.
<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>