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
相关产品推荐
相关产品推荐

