You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps JavaScript API v3标记操作最佳实践咨询

新版Google Maps JavaScript API 类封装最佳实践

核心疑问解答

1. importLibrary 是否会重复加载?

google.maps.importLibrary 自带内部缓存机制,首次调用会从网络加载对应库资源,后续调用会直接返回已加载的模块Promise,不会重复发起网络请求。无需担心重复调用的性能损耗,也可以提前加载所需库并缓存复用。

2. 如何解决顶层await兼容性问题?

部分浏览器暂不支持顶层await,不能直接在类定义外部使用await,可通过以下两种方案处理:


方案一:提前异步加载库后定义类

先加载Maps和Marker库,加载完成后再定义GoogleMap类,确保类内部能直接访问API类:

(async function() {
  // 提前加载所需库并缓存
  const { Map } = await google.maps.importLibrary("maps");
  const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");

  class GoogleMap {
    constructor() {
      this._map = null;
      this._markers = [];
    }

    async init(elem, options = {}) {
      // 直接使用已加载的Map类初始化地图
      this._map = new Map(elem, {
        center: { lat: -34.397, lng: 150.644 },
        zoom: 8,
        ...options
      });
    }

    addMarker(position, options = {}) {
      if (!this._map) {
        throw new Error("请先调用init方法初始化地图");
      }
      const marker = new AdvancedMarkerElement({
        map: this._map,
        position: position,
        ...options
      });
      this._markers.push(marker);
      return marker; // 返回标记实例方便后续操作
    }
  }

  // 示例使用
  const mapContainer = document.getElementById("map");
  const myMap = new GoogleMap();
  await myMap.init(mapContainer);
  myMap.addMarker({ lat: -34.397, lng: 150.644 });
})();

通过异步立即执行函数(IIFE)包裹库加载与类定义,规避顶层await的兼容性问题,同时保证类内部可直接使用已加载的API。


方案二:类内部异步加载库(延迟加载)

若希望按需加载库(仅当实例化地图时才加载),可在类的init方法中处理库加载,并将API类缓存到静态属性中:

class GoogleMap {
  // 静态属性缓存加载后的API类
  static Map = null;
  static AdvancedMarkerElement = null;

  constructor() {
    this._map = null;
    this._markers = [];
  }

  async init(elem, options = {}) {
    // 未加载库时,并行加载所需资源
    if (!GoogleMap.Map || !GoogleMap.AdvancedMarkerElement) {
      [GoogleMap.Map, GoogleMap.AdvancedMarkerElement] = await Promise.all([
        google.maps.importLibrary("maps").then(mod => mod.Map),
        google.maps.importLibrary("marker").then(mod => mod.AdvancedMarkerElement)
      ]);
    }
    // 初始化地图
    this._map = new GoogleMap.Map(elem, {
      center: { lat: -34.397, lng: 150.644 },
      zoom: 8,
      ...options
    });
  }

  addMarker(position, options = {}) {
    if (!this._map) {
      throw new Error("请先调用init方法初始化地图");
    }
    if (!GoogleMap.AdvancedMarkerElement) {
      throw new Error("Marker库未加载,请确保init方法已执行完成");
    }
    const marker = new GoogleMap.AdvancedMarkerElement({
      map: this._map,
      position: position,
      ...options
    });
    this._markers.push(marker);
    return marker;
  }
}

// 示例使用
(async function() {
  const mapContainer = document.getElementById("map");
  const myMap = new GoogleMap();
  await myMap.init(mapContainer);
  myMap.addMarker({ lat: -34.397, lng: 150.644 });
})();

这种方式更灵活,仅首次调用init时加载库,后续实例化会直接复用缓存的静态属性。


关键注意事项

  • init方法必须为异步,需等待库加载完成才能初始化地图,调用时务必使用await。
  • 调用addMarker等依赖API的方法前,需确保init已执行完成,避免因API未加载报错。
  • importLibrary返回Promise,需正确处理异步逻辑,避免未捕获的Promise异常。

内容的提问来源于stack exchange,提问作者Jason Polites

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 00:23:12