node.js - 异步生成反向地理编码地址列表,无 API 速率限制
问题描述
我正在使用我的 Mongo 数据库(使用 Mongoose)中的节点脚本生成测试/开发虚拟数据,其中包括地理位置坐标。(套lat/lon
)。架构如下:
location: {
type: {
type: String,
enum: ["Point"], // 'location.type' must be 'Point'
default: "Point",
},
coordinates: {
type: [Number],
required: true,
},
geocoded: {
type: String, // this has to be done with an external API
},
},
出于这个原因,我有一个外部(付费)反向地理编码 API,我想要/需要为每个文档/坐标集调用它。Geocoding API 虽然有一个速率限制器,所以我遇到了429
- 请求太多。我正在寻找一种干净简单的解决方案来按顺序运行我的请求,并在每个 HTTP 请求之后添加一个限制/等待时间(指定的毫秒数)。
messageSchema.pre("insertMany", async function save(next, docs) {
docs.map(async (doc) => { // now I understand I should replace map with for ... of or for ... in
[err, response] = await to(
reverseGeocode(
doc.location.coordinates[0],
doc.location.coordinates[1]
)
);
if (err) {
next(err);
}
doc.location.geocoded = response;
});
});
reverseGeocode 签名:
reverseGeocode: (lon, lat) =>
axios({
baseURL: "https://eu1.locationiq.com/",
url: "v1/reverse.php",
params: {
lat,
lon,
key: geocodeKey,
},
}).then((response) => response.data),
解决方案
我使用这个库来限制请求。您只需告诉它 API 的速率限制是多少,您就可以随心所欲地调用它,它会随着时间的推移自动为您分配请求。
如果您不想要另一个依赖项,那么要使您的解决方案工作,您需要使用for
循环。map
将始终尽可能快地执行。
const wait = (time) => {
return new Promise((resolve) => {
setTimeout(resolve, time);
});
}
messageSchema.pre("insertMany", async function(next, docs) {
for(let i in docs) {
const doc = docs[i];
await wait(3000); // milliseconds to space requests out by.
const response = await reverseGeocode(
doc.location.coordinates[0],
doc.location.coordinates[1]
);
}
console.log(this);
});
推荐阅读
- django - 如何正确地将 Django 序列化数据附加到 Excel 工作表中
- google-sheets - 尽管添加了新行,但仍锁定 Google 表格中的一行
- typescript - 打字稿字符串和字符串枚举 - 字符串不可分配
- mysql-cluster - MySQL启动失败导致LSB启动失败
- javascript - 将两个字符串转换为浮点数 (JavaScript)
- ios - 如何在 SwiftUI 中收到 EKEventStore 权限更改的通知?
- excel - VBA 解压缩密码保护的 ZIP 文件
- java - 我可以看到/研究什么来了解 JpaRepository 如何通过包含实体的动态字段的方法的名称来实现代码?
- swagger - springdoc-openapi-ui web view无法应用自定义openapi文档
- javascript - 需要幻灯片居中并固定按钮