Node.js异步数据保留问题:Telegram Bot无法返回streetName
解决Node.js异步操作导致无法获取streetName的问题
你的问题核心是异步代码的执行顺序:geoCoder.geocode()是异步操作,.then()里的赋值逻辑会在主线程代码(console.log(msg)和return语句)之后执行,所以返回的时候msg还是空字符串。文件读写也是异步操作,自然也会遇到同样的顺序问题,而且完全没必要用这种方式绕路。
直接用async/await就能简单解决,这是最适合初学者理解的异步处理方式,修改后的代码如下:
// 把模块require移到函数外面,避免每次调用都重复加载 const nodeGeocoder = require('node-geocoder'); // 把函数声明为async,这样内部可以用await const Geolocation = async (req) => { var address = "15 Freedom Way, Jersey City, NJ 07305, United States"; let msg = ""; const param = { provider: 'openstreetmap' }; const geoCoder = nodeGeocoder(param); try { // 用await等待异步操作完成,直接拿到结果 const res = await geoCoder.geocode(address); msg = res[0].streetName; console.log(msg); // 现在这里能输出正确的streetName了 } catch (err) { console.log(err); // 可以在这里加错误处理逻辑,比如给msg赋值默认提示 msg = "获取地址信息失败"; } // 现在msg已经有正确的值了,再返回格式化后的响应 return UTILS.formatDialogflowResponse( msg, [] ); }
关键改动说明:
- 把
Geolocation改成async函数:这是使用await的前提 - 用
await替代.then():让异步代码看起来像同步代码一样执行,等待geoCoder.geocode()完成后再继续往下走 - 用
try/catch捕获错误:替代原来的.catch(),逻辑更集中清晰 - 把
require移到函数外:模块只需要加载一次,不用每次调用函数都重复加载
这样修改后,就能确保msg拿到正确的streetName后,再传入UTILS.formatDialogflowResponse作为返回值了。
内容的提问来源于stack exchange,提问作者kekko4000
相关产品推荐
相关产品推荐

