Reputation: 1122
I am using Google geocoding in my code. I have to geocode about 50 places,
but Google doesn't allow to geocode so many places at the same time, generating a 'OVER_QUERY_LIMIT' error.
So I want do delay the geocoding for few seconds when I exceed the quota.
I have a function geocode()
that returns a promise
. When I exceed quota, I want to recursively call itself.
This is my not-working code:
function geocodeAll(addresses)
{
for (addr in addresses)
{
geocode(addresses[addr])
.then(
function(coord)
{/* I don't always get here */}
)
}
}
function geocode(address)
{
var deferred = Q.defer();
geocoder.geocode(address, function ( err, geoData )
{
if (err)
{ deferred.reject(err);}
else
{
if (geoData.status=="OVER_QUERY_LIMIT" )
{ // doh! quota exceeded, delay the promise
setTimeout(function()
{geocode(address)
.then(
function(coord)
{deferred.resolve(coord);}
);
}, 1000);
}
else
{ // everything ok
var coord = {'lat':geoData.lat, 'lng':geoData.lng};
deferred.resolve(coord);
}
}
});
return deferred.promise;
}
UPDATE [solved]
actually the code is right. I had an uncaughtException not related to the delay. Using Q.all([..]).then().catch()
I found it
Upvotes: 3
Views: 204
Reputation: 5443
Your code seems to work fine. The only issue i see with your code is that you are using lat
and lng
out of scope. But you may have written that correctly and you're just not including the code. I suspect though that you may have been using the two in error. Should those have been geoData.lat
and geoData.lng
?
var coord = { 'lat': geoData.lat, 'lng': geoData.lng };
EDIT
I think your problem might have to do with your geocodeAll
function implementation.
function geocodeAll(addresses)
{
for (addr in addresses)
{
geocode(addresses[addr]) /* This seems error prone to me! Try keeping track of all your promises.*/
.then(
function(coord)
{/*You only get here if there was no error returned from the geo request to the api. */}
)
}
}
Keep track using Q.all
,
function geocodeAll(addresses) {
var promises = addresses.map(geocode);
for (addr in addresses) {
promises.push(
geocode(addresses[addr])
.catch(console.log.bind(console)) /* handle your error however you see fit*/
);
}
return Q.all(promises).then(function(results) {
var firstCord = results[0];
var secondCord = results[1];
//etc...
});
}
Or you can additionally handle the success/fail using Q.allSettled
function geocodeAll(addresses) {
var promises = addresses.map(geocode);
return Q.allSettled(promises).then(function (results) {
var success = [], fail = [];
results.forEach(function (result) {
if (result.state === "fulfilled") {
success.push(result.value);
} else {
fail.push(result.reason);
}
});
return { coords: success, errors: fail };
});
}
});
Upvotes: 2
Reputation: 33650
Code looks good. Perhaps geocoder.geocode
or something else is erring. Try setting:
window.onerror = (err) => console.error(err)
Or:
process.on('uncaughtException', (err) => console.error(err))
Upvotes: 0