Vue2+OpenLayers无服务器项目循环内指定方法按顺序执行方案咨询
实现方案
核心用原生ES2017支持的async/await结合OpenLayers自带的rendercomplete事件实现严格顺序执行,不需要引入任何第三方库。
第一步:封装渲染完成等待函数
将OpenLayers的渲染完成事件包装为Promise,用于异步等待所有图层(包括远程WMS瓦片图层)加载渲染完毕:
function waitForMapRenderComplete(map, timeout = 10000) { return new Promise((resolve, reject) => { // 超时处理,避免图层加载失败导致流程卡死 const timeoutTimer = setTimeout(() => { map.un('rendercomplete', onRenderComplete); reject(new Error('地图渲染超时,请检查图层配置')); }, timeout); const onRenderComplete = () => { clearTimeout(timeoutTimer); map.un('rendercomplete', onRenderComplete); resolve(); }; map.on('rendercomplete', onRenderComplete); }); }
第二步:编写串行执行的循环逻辑
将每轮的三个操作按顺序封装到async循环中,保证上一轮所有操作执行完成后才会进入下一轮:
// 可以直接作为Vue的方法使用 async function batchAddGifFrames(loopCount) { for (let i = 0; i < loopCount; i++) { // 1. 更新图层TIME参数 this.setTimeSurface10(); // 2. 触发地图同步渲染 this.map.renderSync(); // 3. 等待所有图层渲染完成 await waitForMapRenderComplete(this.map); // 4. 提取当前画布内容添加为GIF帧 this.myCallback(); } // 所有帧添加完成,可在此处调用GIF导出逻辑 this.gif.render(); console.log('GIF帧批量添加完成'); }
调用方式
需要执行72次就传72,需要按dateArraySurface10长度循环就传对应长度即可:
// 示例:按时间数组长度执行 this.batchAddGifFrames(this.dateArraySurface10.length - 1);
适配多图层扩展
如果需要支持用户添加任意数量的图层,仅需修改参数更新步骤的逻辑:
// 示例:通用多图层参数更新方法 function updateAllLayersTime(currentTime) { // 遍历所有需要更新时间的图层 this.dynamicLayers.forEach(layer => { layer.getSource().updateParams({ TIME: currentTime.toISOString().split(".")[0] + "Z" }); }); }
将原循环中的this.setTimeSurface10()替换为上述通用方法即可,其余逻辑无需改动。
原有写法问题说明
你之前的waterfall写法存在语法错误:async.waterfall要求数组参数为接收回调的函数,你直接传入this.setTimeSurface10()相当于立即执行函数并将返回值传入,无法实现串行控制;同时未等待远程WMS瓦片加载完成就执行抓帧逻辑,会导致导出帧内容错误。
小提示:问题描述中提到的方法名
setTiimeSurface10存在拼写错误,多了一个字母i,注意和实际代码中的setTimeSurface10保持一致,避免调用报错。
内容的提问来源于stack exchange,提问作者Curious
相关产品推荐
相关产品推荐

