我有来自 MongoDB 的 13.000 个文档,其中有地址行 + 邮政编码,我试图为每个文档向 Google 的地理编码 API 发出请求,并为它们获取 LAT + LONG,以便我可以让它们动态出现在地图搜索中。
我设计了以下 for of 循环,一次测试 10 个项目,但由于写入 DB 调用和调用 API 的异步性质,来自 HTTPS 请求的 LAT/LONG 坐标最终未定义/unavailable to knex's INSERT 并且循环似乎一直在继续......
是否可以以阻塞方式编写它?因此,除非两个承诺都已解决,否则 for 循环不会转到下一项?
编码:
let results = [];
await forLoop();
async function forLoop() {
for (job of allJobs) {
const geoData = await getGeoData(
job.site.addressLine1,
job.site.postcode
);
const dbResult = await addToDb(geoData);
results.push(dbResult);
async function getGeoData(addressLine1, postcode) {
const friendlyAddress = encodeURIComponent(addressLine1 + ' ' + postcode);
https
.get(
'https://maps.googleapis.com/maps/api/geocode/json?key=<API_KEY_IGNORE_THIS_ITS_HARDCODED_IN_MY_REAL_CODE>&address=' +
friendlyAddress,
resp => {
let data = '';
resp.on('data', chunk => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data).explanation);
let result = JSON.parse(data);
return result;
});
}
)
.on('error', err => {
console.log('Error: ' + err.message);
});
}
async function addToDb(geoData) {
try {
await knex('LOCATIONS')
.returning('*')
.insert({
UPRN: job.site.UPRN,
lat: geoData.results[0].geometry.location.lat,
lng: geoData.results[0].geometry.location.lng
});
} catch (err) {
err.name = 'database';
next(err);
}
}
}
}
res.send(results);
我确保代码库没有空值,并测试了 api 调用和数据库调用,以确保它们独立工作。