为何geocoder.geocode返回的结果无法赋值到函数外层results变量?
为啥回调里的results没法赋值到外层变量?
这个问题我当初刚接触异步代码的时候也踩过一模一样的坑!核心原因是**geocoder.geocode是一个异步操作**,它的执行逻辑和你想的同步代码完全不一样。
先给你捋一遍这段代码的实际执行顺序:
- 你声明了
let results = [],这时候它就是个空数组。 - 调用
geocoder.geocode(),这个方法不会傻等地理编码请求完成才继续——它会立刻发起请求,然后把后面的回调函数“挂”在任务队列里,等请求有结果了再去执行。 - 紧接着就执行了
console.log("out of scope", results),这时候回调函数还没被触发呢,所以results还是你一开始声明的空数组。 - 等地理编码请求完成(可能是几毫秒甚至几百毫秒后),浏览器才会去执行回调函数里的代码,这时候
console.log("in scope", results)输出的才是正确结果,但这里的return results只是从回调函数里返回,根本不会影响外层getSearchLocation里的results变量——因为外层函数早就执行完了!
那该怎么拿到正确的结果呢?给你两个常用的解决方案:
方案一:用回调函数传递结果
把处理结果的逻辑放到回调里,或者给getSearchLocation传一个回调参数:
getSearchLocation(callback){ geocoder.geocode( { 'address': address}, function(results, status) { // 记得先判断状态是否成功 if (status === 'OK') { console.log("in scope", results); callback(null, results); // 成功时把结果传出去 } else { callback(new Error(`地理编码失败: ${status}`), null); // 失败时传错误信息 } }); } // 调用的时候这么用 getSearchLocation((err, results) => { if (!err) { console.log("拿到结果啦!", results); // 在这里处理你的结果数组 } else { console.error(err); } });
方案二:用Promise封装(推荐,代码更清晰)
把异步操作包装成Promise,这样就能用async/await写同步风格的异步代码了:
function getSearchLocation() { return new Promise((resolve, reject) => { geocoder.geocode( { 'address': address}, function(results, status) { if (status === 'OK') { console.log("in scope", results); resolve(results); // 成功时返回结果 } else { reject(new Error(`地理编码失败: ${status}`)); // 失败时抛出错误 } }); }); } // 调用的时候用async/await async function handleSearch() { try { const results = await getSearchLocation(); console.log("拿到结果啦!", results); // 在这里处理结果 } catch (err) { console.error("出错了:", err); } } // 执行函数 handleSearch();
总结一下:异步操作的结果没法直接在同步代码里返回,必须用回调、Promise这类异步模式来处理结果。
内容的提问来源于stack exchange,提问作者clusterBuddy
相关产品推荐
相关产品推荐

