Глобальный объект, загруженный через внешний CDN, используемый в обратном вызове, недоступен во время выполнения - PullRequest
0 голосов
/ 20 января 2019

Я использую BingMaps Api. Я использую JavaScript для добавления тега script в DOM, который загружает CDN. Затем я объявляю глобальную функцию для использования в качестве обратного вызова при загрузке CDN, как сказано в документации.

Тем не менее, когда выполняется обратный вызов, я получаю сообщение «TypeError: Microsoft.Map не является конструктором».

Когда я набираю «Microsoft» в консоли, я вижу, что она есть. Эта проблема не возникает, когда я помещаю скрипт прямо в HTML. Почему это?

Код можно просмотреть и выполнить в этой песочнице: https://codesandbox.io/s/1z4o7km3ml

// insert script tag into DOM

const bingScript = document.createElement("script");
bingScript.type = "text/javascript";
bingScript.src =
  "https://www.bing.com/api/maps/mapcontrol?callback=onLoadApi";
document.head.appendChild(bingScript);

//insert div element into DOM
const mapDiv = document.createElement("div");
mapDiv.id = "bingMap";
mapDiv.setAttribute("style", 
"position:relative;width:600px;height:400px;");
document.body.appendChild(mapDiv);

window.onLoadApi = () => {
  try {
    const map = new 
window.Microsoft.Map(document.getElementById("bingMap"), {
      credentials:
        <API KEY>
    });
  } catch (e) {
    console.error(e);
  }
};

Ответы [ 2 ]

0 голосов
/ 23 января 2019

На самом деле все в порядке с вашим примером, за исключением строки, в которой создается экземпляр объекта карты:

const map = new window.Microsoft.Map(document.getElementById("bingMap"), {
                ^^^^^^^^^^^^^^^^^^^^ 
  credentials: API_KEY
});

Здесь есть опечатка, Map класс объявлен в Microsoft.Maps пространство имен , но не в Microsoft пространстве имен, как в вашем примере, вот причина возникновения указанной ошибки:

TypeError: window.Microsoft.Map не является конструктором

0 голосов
/ 20 января 2019

Понятия не имею, почему предыдущий код не работал. Даже после установки времени ожидания в течение пяти секунд перед запуском функции createMap () объект Microsoft все еще не был доступен. Если кто-то может пролить понимание, это все равно будет высоко ценится. Но решение состоит в том, чтобы обернуть обратный вызов в обещание.

import "./styles.css";
let initializedPromise = null
//insert div element into DOM
const mapDiv = document.createElement("div");
mapDiv.id = "bingMap";
mapDiv.setAttribute("style", "position:relative;width:600px;height:400px;");
document.body.appendChild(mapDiv);

const insertBingScriptIntoDom = () => {
  const bingScript = document.createElement("script");
  bingScript.type = "text/javascript";
  bingScript.src =
    "https://www.bing.com/api/maps/mapcontrol?callback=onLoadApi;
  document.body.appendChild(bingScript);
};

const initApi = () => {
  if (!initializedPromise) {
    initializedPromise = new Promise((resolve, reject) => {
      window.onLoadApi = () => {
        resolve()
      }
    })
    insertBingScriptIntoDom()
  }
  return initializedPromise
}

const createMap = async () => {
  await initApi()
  new window.Microsoft.Maps.Map(mapDiv, {
    credentials: <API KEY>,
    center: window.Microsoft.Maps.Location(41.6, 2.9)
  })
}

createMap()
...