如何在require回调外部访问ArcGIS JavaScript API
最优实现方案:全局任务队列(兼容遗留代码+彻底解决时序问题)
这个方案无需重构现有应用整体逻辑,只会新增3个全局变量,完全避免API未加载完成就被调用的问题:
- 首先在所有业务代码之前的全局作用域定义状态标记和任务队列
// 全局定义,所有代码执行前先声明 window.arcgisReadyQueue = [] window.arcgisAPI = null let isArcgisLoaded = false
- 改造原有的require回调,加载完成后暴露需要的所有API、实例、方法,再批量执行排队的任务
require(["esri/config", "esri/Map", "esri/views/MapView", "esri/Graphic", "esri/layers/GraphicsLayer", "esri/layers/FeatureLayer" ], function(esriConfig, Map, MapView, Graphic, GraphicsLayer, FeatureLayer) { esriConfig.apiKey = ""; const map = new Map({ basemap: "arcgis-topographic" }); const view = new MapView({ map: map, center: [-81, 41], zoom: 9, container: "viewDiv" }); // 对外暴露所有需要用到的模块、实例、操作方法 window.arcgisAPI = { map, view, Graphic, GraphicsLayer, FeatureLayer, // 添加点位方法 plotPoint: (lat, long, props) => { const popupTemplate = { title: "{Name}", content: "{Description}" } const attributes = { Name: props.name, Description: props.desc } // 建议这里复用同一个GraphicsLayer,不需要每次调用都新建,性能更好 const graphicsLayer = new GraphicsLayer(); map.add(graphicsLayer); const point = { type: "point", longitude: long, latitude: lat }; const simpleMarkerSymbol = { type: "simple-marker", color: [226, 119, 40], outline: { color: [255, 255, 255], width: 1 } }; const pointGraphic = new Graphic({ geometry: point, symbol: simpleMarkerSymbol, attributes: attributes, popupTemplate: popupTemplate }); graphicsLayer.add(pointGraphic); // 返回图层实例方便后续删除 return graphicsLayer }, // 扩展其他需要的操作方法 removeLayer: (layer) => map.remove(layer), addFeatureLayer: (config) => map.add(new FeatureLayer(config)) } // 标记加载完成,执行所有排队的任务 isArcgisLoaded = true window.arcgisReadyQueue.forEach(task => task(window.arcgisAPI)) });
- 外部任意位置调用的统一写法,自动适配API加载状态
// 可以提前把这个调用函数也定义在全局,所有业务代码都可以直接用 function runWhenArcgisReady(task) { if (isArcgisLoaded) { task(window.arcgisAPI) } else { window.arcgisReadyQueue.push(task) } } // 示例:业务代码中要添加点位 runWhenArcgisReady(api => { const pointLayer = api.plotPoint(41, -81, {name: '测试点位', desc: '点位描述'}) // 后续需要删除点位直接调用 // api.removeLayer(pointLayer) })
其他可选方案
如果遗留代码中已经在使用AMD模块规范,可以把ArcGIS初始化逻辑封装成独立的AMD模块,其他业务模块直接依赖这个模块即可保证加载顺序,不需要额外处理时序问题。
内容的提问来源于stack exchange,提问作者JoshG
相关产品推荐
相关产品推荐

