Ich versuche Längen- und Breitengrad aus einer Liste von Adressen mit der Google API über ein Node.js-Skript abzurufen. Der Anruf selbst funktioniert einwandfrei, da ich aber rund 100 Adressen einreichen muss. Ich benutze eine async.forEach
auf einem Array, aber die Anrufe werden zu schnell gemacht und ich bekomme den Fehler "Sie haben Ihre Rate-Limit für diese API überschritten."Führe einen ForEach wie einen Wasserfall in Async aus
Ich fand, dass die Anzahl der Anrufe auf 2500 alle 24 Stunden und maximal 10 Sekunden begrenzt ist. Während ich für die 2500 pro Tag OK bin, mache ich meine Anrufe viel zu schnell für das Ratenlimit.
Ich muss jetzt eine Funktion schreiben, wer die Anrufe genug verzögert, um das Limit nicht zu erreichen. Hier ist ein Beispiel von meinem Code:
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
});
Wie würden Sie vorgehen, dies zu erreichen? Ich habe versucht, mein Putting rest.getJSON
in einem 100ms setTimeout
aber die forEach
wird für alle Reihen so schnell, dass alles beginnt die setTimeout
fast zur gleichen Zeit und daher ist es nicht etwas ändern ...
The async.waterfall
wie es aussieht, würde den Trick machen, aber die Sache ist, ich weiß nicht genau, wie viele Zeilen ich haben werde, also kann ich nicht alle Funktionsaufrufe fest codieren. Und um ehrlich zu sein, würde es meinen Code machen wirklich hässlich
Haben Sie Rekursion versucht? Verwenden Sie den Rückruf, um ein Zeitlimit festzulegen, um die Abruffunktion nach 100 ms rekursiv aufzurufen. –
Dies scheint ein generisch genug Problem, dass eine allgemeine Lösung angemessen ist. Rate-limiting ist ein gängiges Konstrukt und inline setTimeout-Hacks sind wahrscheinlich nicht der richtige Weg. Der Wasserfall kann langsamer oder schneller als nötig sein, da er nur auf die Rückkehr des letzten Anrufs wartet. Wenn ein Anruf weniger als 1/10 Sekunde dauert, bist du immer noch zu schnell. –
Warum nicht etwas Einfaches wie "Parallel" mit 10 eingereihten, wenn sie abgeschlossen sind, stellen Sie sicher, dass insgesamt 10 Sekunden vergangen sind, bevor Sie den nächsten Stapel starten? – WiredPrairie