通过外部CDN加载的全局对象在回调中使用,在运行时不可用

时间:2019-01-20 17:09:48

标签: javascript asynchronous dom bing-maps cdn

我正在使用BingMaps Api。我使用JavaScript将脚本标签附加到加载CDN的DOM中。然后,我按照文档中的说明声明了在加载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 :(得分:0)

我不知道为什么以前的代码不起作用。即使在运行createMap()函数之前将超时设置为五秒钟之后,Microsoft对象仍然不可用。如果有人可以发挥见识,仍然会非常感激。但是解决方案是将回调包装在promise中。

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()

答案 1 :(得分:0)

实际上,您的示例一切正常,除了实例化地图对象的行:

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

这里有一个错字,在Map class下声明了Microsoft.Maps namespace,但是在您的示例中,Microsoft下的命名为不是,这就是为什么要指定错误发生:

  

TypeError:window.Microsoft.Map不是构造函数