Mapbox-gl 异步动态加载资源 回调问题解决

759 阅读1分钟

Mapbox-gl 动态加载资源

// A.
const layer = this.map.addLayer({
    id: 'defaultEmeArea',
    type: 'fill',
    source: 'mapSource',
    paint: {
      'fill-color': [
        'case',
        ['==', ['feature-state', 'selectCount'], 1], 'rgba(52, 171, 255, 0.35)',
        ['==', ['feature-state', 'selectCount'], 2], '#34abff',
        'transparent'
      ],
      'fill-opacity': [
        'case',
        ['==', ['feature-state', 'selectCount'], 1], 1,
        ['==', ['feature-state', 'selectCount'], 2], 0.35,
        1
      ]
    }
  })
}
// B.
this.setFilterFeature(this.filterDefaultAreaList, 'defaultEmeArea', 'mapSource', 1)

说明:
1、addLayer添加层时,异步资源加载没有完成(mapSource资源没有加载完成)。
2、同步代码时候存在问题 执行A->B时问题出现,addLayer 等待资源加载,而 setFilterFeature 无法获取layerId = defaultEmeArea 层的操作。
3、使用map event无法处理这类问题,包括idle、sourcedata。问题出现原因 猜测是 js 主线程 与 webgl线程。

解决方案:

/**
 * Call a function when the map's style has loaded. You can safely add and
 * modify map layers within this function
 *
 * @param {mapboxgl.Map} map
 * @param {function} fn
 */
function onMapStyleLoaded (map, fn) {
  if (map.isStyleLoaded()) return process.nextTick(fn)
  map.once('styledata', () => onMapStyleLoaded(map, fn))
}

/**
 * Call a function when the map's tiles have loaded, i.e. most network activity
 * is complete (although sprite and font loading may still be occurring)
 *
 * @param {mapboxgl.Map} map
 * @param {function} fn
 */
function onMapTilesLoaded (map, fn) {
  if (map.areTilesLoaded()) return process.nextTick(fn)
  map.once('sourcedata', () => onMapTilesLoaded(map, fn))
}

/**
 * Call a function when the map has finished rendering and transitions are
 * complete
 *
 * @param {mapboxgl.Map} map
 * @param {function} fn
 */
function onMapRenderComplete (map, fn) {
  if (map.loaded()) return process.nextTick(fn)
  map.once('render', () => onMapRenderComplete(map, fn))
}

注:不同框架可以替换 process.nextTick