如何在Google Maps回调函数中保留全局变量contor的更新值?
解决Google Maps异步回调导致全局变量未更新的问题
你遇到的问题本质是异步操作的时序问题:nearbySearch是Google Maps提供的异步API——你的processImobs函数会同步遍历所有availableImobs,立刻调用processEachImob,但nearbySearch不会等待结果返回就继续执行下一次循环。等你在processImobs里尝试访问contor时,所有的回调函数还没开始执行,所以contor还是初始值0。
下面给你几个可行的解决方案,从现代的异步语法到传统的回调方式都有:
方案1:用Promise + async/await(推荐,代码更清晰)
我们可以把nearbySearch封装成返回Promise的函数,然后用async/await等待所有异步操作完成,这样就能确保在访问contor时,所有回调都已经执行完毕。
修改processEachImob为Promise风格
function processEachImob(imob) { return new Promise((resolve) => { const service = new google.maps.places.PlacesService(map); service.nearbySearch({ location: new google.maps.LatLng(imob[0], imob[1]), radius: 500, type: ['pharmacy'] }, function callBack(results, status) { markersP = []; if (status == google.maps.places.PlacesServiceStatus.OK) { for (var i = 0; i < results.length; i++) { createPharmaciesMarker(results[i]); } if (markersP.length !== 0) { for(var i=0; i < markersP.length; ++i){ ++contor; const latLng = [markersP[i].position.lat(), markersP[i].position.lng()]; queue.add(imob, latLng, 'pharmacy'); } } } resolve(); // 标记当前异步操作完成 }); }); }
修改processImobs为async函数
let contor = 0; // 尽量用let替代var,避免变量提升问题 async function processImobs(){ // 收集所有异步操作的Promise const asyncTasks = availableImobs.map(imob => processEachImob(imob)); // 等待所有异步任务完成 await Promise.all(asyncTasks); // 现在contor已经是更新后的最终值了 console.log("最终contor值:", contor); }
方案2:用计数器+回调函数(兼容旧环境)
如果你的项目不能使用ES6+的async语法,可以手动用计数器跟踪所有异步操作的完成状态,等全部完成后再处理contor。
修改processEachImob接受完成回调
function processEachImob(imob, onTaskComplete){ const service = new google.maps.places.PlacesService(map); service.nearbySearch({ location: new google.maps.LatLng(imob[0], imob[1]), radius: 500, type: ['pharmacy'] },function callBack(results, status){ markersP = []; if (status == google.maps.places.PlacesServiceStatus.OK){ for (var i = 0; i < results.length; i++) { createPharmaciesMarker(results[i]); } if( markersP.length !== 0){ for(var i=0; i < markersP.length; ++i){ ++contor; const latLng = [markersP[i].position.lat(), markersP[i].position.lng()]; queue.add(imob, latLng, 'pharmacy'); } } } // 通知当前任务完成 onTaskComplete(); }); }
修改processImobs跟踪任务完成情况
let contor = 0; function processImobs(onAllComplete){ const totalTasks = availableImobs.length; let completedTasks = 0; // 没有数据直接触发回调 if(totalTasks === 0){ onAllComplete(); return; } for(let i = 0; i < totalTasks; ++i){ processEachImob(availableImobs[i], () => { completedTasks++; // 所有任务完成后,触发回调 if(completedTasks === totalTasks){ console.log("最终contor值:", contor); onAllComplete(); } }); } } // 使用方式: processImobs(() => { // 所有操作完成后的逻辑写在这里 });
额外优化:避免全局变量contor
全局变量容易引发意外的副作用,我们可以让每个processEachImob返回本次新增的数量,最后在processImobs里累加,这样更安全:
function processEachImob(imob) { return new Promise((resolve) => { const service = new google.maps.places.PlacesService(map); let addedCount = 0; service.nearbySearch({ location: new google.maps.LatLng(imob[0], imob[1]), radius: 500, type: ['pharmacy'] }, function callBack(results, status) { markersP = []; if (status == google.maps.places.PlacesServiceStatus.OK) { for (var i = 0; i < results.length; i++) { createPharmaciesMarker(results[i]); } if (markersP.length !== 0) { addedCount = markersP.length; for(var i=0; i < markersP.length; ++i){ const latLng = [markersP[i].position.lat(), markersP[i].position.lng()]; queue.add(imob, latLng, 'pharmacy'); } } } resolve(addedCount); // 返回本次新增的数量 }); }); } async function processImobs(){ const counts = await Promise.all(availableImobs.map(imob => processEachImob(imob))); const totalContor = counts.reduce((sum, count) => sum + count, 0); console.log("最终总数:", totalContor); }
内容的提问来源于stack exchange,提问作者Dalisay
相关产品推荐
相关产品推荐

