【发布时间】:2023-03-16 01:56:01
【问题描述】:
我正在尝试使用 Google API 通过 Node.js 脚本从地址列表中检索经度和纬度。调用本身工作正常,但因为我有大约 100 个地址要提交。我在数组上使用了async.forEach,但调用速度太快,并且出现错误“您已超出此 API 的速率限制。”
我发现呼叫次数限制为每 24 小时 2500 次,每秒最多 10 次。虽然我可以接受每天 2500 次的通话,但由于速率限制,我的通话速度太快了。
我现在必须编写一个函数来延迟调用,使其不会达到限制。这是我的代码示例:
async.forEach(final_json, function(item, callback) {
var path = '/maps/api/geocode/json?address='+encodeURIComponent(item.main_address)+'&sensor=false';
console.log(path);
var options = {
host: 'maps.googleapis.com',
port: 80,
path: path,
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}
// a function I have who makes the http GET
rest.getJSON(options, function(statusCode, res) {
console.log(res);
callback();
});
}, function() {
// do something once all the calls have been made
});
您将如何继续实现这一目标?我尝试将我的rest.getJSON 放在 100 毫秒内 setTimeout 但forEach 迭代所有行的速度非常快,以至于它几乎同时启动了所有setTimeout,因此它不会改变任何东西......
async.waterfall 看起来可以解决问题,但问题是我不知道我将拥有多少行,所以我无法对所有函数调用进行硬编码。老实说,这会让我的代码非常难看
【问题讨论】:
-
你试过递归吗?使用回调设置超时,100ms 后递归调用 fetch 函数。
-
这似乎是一个足够通用的问题,因此通用解决方案是合适的。速率限制是一种常见的构造,内联 setTimeout hack 可能不是正确的方法。瀑布可能比必要的更慢或更快,因为它所做的只是等待最后一个调用返回。如果通话时间不到 1/10 秒,你还是太快了。
-
为什么不使用像
parallel这样简单的东西,有 10 个队列,当它们完成时,确保在开始下一批之前总共经过了 10 秒? -
这是一个简洁的版本。我一直在思考和编写循环,等待 125 毫秒 + 一个用于尚未返回结果的存储桶。循环会将项目放入存储桶中,http 回调将删除它们。不要让桶变得大于10,并且不要以超过8/秒的速度推入桶。当它完成并且桶是空的(等待它,等待它......)执行你的“全部完成功能”
标签: javascript node.js asynchronous google-api