JavaScript中如何等待首个函数返回值后执行后续函数?
异步函数调用后返回undefined的解决方法
原始代码
你拥有两个调用AWS Location API的异步函数:
const AWS = require('aws-sdk'); const location = new AWS.Location({ region: "us-east-1" }); async function calculateCoordinates(INDEX_NAME, ADDRESS_BLOCK) { return new Promise((resolve, reject) => { var params = { IndexName: INDEX_NAME, Text: ADDRESS_BLOCK, }; location.searchPlaceIndexForText(params, function (err, data) { if (err) { console.log(err, err.stack); reject(err); } else { var coordinates = []; coordinates.push(data.Summary.ResultBBox[0]); coordinates.push(data.Summary.ResultBBox[1]); resolve(coordinates); } }); }); } async function extractCountry(INDEX_NAME, LAT, LON) { return new Promise((resolve, reject) => { var params = { IndexName: INDEX_NAME, Position: [LAT, LON], }; location.searchPlaceIndexForPosition(params, function (err, data) { if (err) { console.log(err, err.stack); reject(err); } else { resolve(data.Results[0].Place.Country); } }); }); }
问题场景
你需要先执行calculateCoordinates获取坐标,再将坐标传入extractCountry查询国家,但调用后country始终返回undefined。嵌套的then已经保证了函数执行顺序,问题出在其他细节上。
问题原因
- 坐标参数顺序错误:AWS Location API的
searchPlaceIndexForPosition接口要求Position参数格式为[经度, 纬度],但你在extractCountry中写成了[LAT, LON](纬度在前),导致查询位置无效,无法识别国家。 - 使用边界框坐标而非精准地址坐标:
data.Summary.ResultBBox是查询结果的边界框范围(格式为[minLon, minLat, maxLon, maxLat]),你取的前两个值是边界框的西南角坐标,而非目标地址的精准经纬度,可能导致位置偏离有效区域。
修正方案
1. 修正坐标顺序与精准度
修改calculateCoordinates使用目标地址的精准经纬度,同时调整extractCountry的Position参数顺序:
const AWS = require('aws-sdk'); const location = new AWS.Location({ region: "us-east-1" }); async function calculateCoordinates(INDEX_NAME, ADDRESS_BLOCK) { return new Promise((resolve, reject) => { const params = { IndexName: INDEX_NAME, Text: ADDRESS_BLOCK, }; location.searchPlaceIndexForText(params, (err, data) => { if (err) { console.log(err, err.stack); reject(err); } else { // 检查是否有有效查询结果 if (!data.Results || data.Results.length === 0) { reject(new Error('未找到匹配的地址')); return; } // 使用第一个结果的精准经纬度,格式为[经度, 纬度] const preciseCoords = data.Results[0].Place.Geometry.Point; resolve(preciseCoords); } }); }); } async function extractCountry(INDEX_NAME, lon, lat) { return new Promise((resolve, reject) => { const params = { IndexName: INDEX_NAME, Position: [lon, lat], // 修正为[经度, 纬度]顺序 }; location.searchPlaceIndexForPosition(params, (err, data) => { if (err) { console.log(err, err.stack); reject(err); } else { // 检查是否有有效查询结果 if (!data.Results || data.Results.length === 0) { reject(new Error('该坐标未匹配到有效地点')); return; } resolve(data.Results[0].Place.Country); } }); }); }
2. 优化调用代码(用async/await更清晰)
替代嵌套then,代码可读性更强,错误处理更集中:
async function getCountryFromAddress(indexName, address) { try { const coordinates = await calculateCoordinates(indexName, address); console.log('精准坐标:', coordinates); const country = await extractCountry(indexName, coordinates[0], coordinates[1]); console.log('国家:', country); return country; } catch (error) { console.error('流程失败:', error); } } // 调用示例 getCountryFromAddress('INDICEDIPOSIZIONE', 'ROMA');
额外说明
- 增加了空结果检查,避免因无查询结果导致的
undefined访问错误; - 精准经纬度比边界框坐标更能保证查询准确性,减少返回
undefined的概率。
内容的提问来源于stack exchange,提问作者WonderWhy
相关产品推荐
相关产品推荐

