How to re-run a javascript promise when failed?
Asked Answered
N

2

1

I have the following code where I am trying to convert a list of 10-15 addresses in the businesses array into lat/lng coordinates using Google Maps Geocoding API.

var geocoder = new google.maps.Geocoder();

var proms = businesses.map(function(address) {
    return prom = new Promise(function(resolve) {
       geocoder.geocode({
            address: address
        }, function(results, status) {

            if (status === google.maps.GeocoderStatus.OK) {
                resolve({
                    results: results,
                    business: address
                });

            } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                setTimeout(function() {
                    //HOW DO I RE-RUN THIS "new Promise"?
                }, 1000);

            } else {
                console.log(status + ': ' + results);
            }

        });
    });
});
Promise.all(proms);

The problem is that Google's API will sometimes return an OVER_QUERY_LIMIT error so I was wondering if there's a way to re-run the promise that failed after a few seconds. In the example above the else if statement catches the error, so how would I make it rerun after a timeout?

Note that I just started using promises and don't have a good understanding yet how they work so my approach might be completely wrong. Also all of this is done under the assumption that Google's API won't let me resolve addresses in bulk, if that's not the case - please, let me know.

Nonalignment answered 20/11, 2014 at 15:35 Comment(0)
S
2

You can put the main body of code into a function and call it again from the timer. Note: this is not technically rerunning a promise, it's rerunning a block of code that will then resolve the promise when done:

var proms = businesses.map(function(address) {
    return prom = new Promise(function(resolve, reject) {
        var retriesRemaining = 5;
        function run() {
            geocoder.geocode({
                    address: address
                }, function(results, status) {

                    if (status === google.maps.GeocoderStatus.OK) {
                        resolve({
                            results: results,
                            business: address
                        });

                    } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                        --retriesRemaining;
                        if (retriesRemaining <= 0) {
                            reject(status);
                        } else {
                            setTimeout(run, 1000);
                        }
                    } else {
                        console.log(status + ': ' + results);
                    }

                }
            });
        }
        run();
    });
});
Promise.all(proms);

FYI, I also added a retry count so the code can never get stuck in an error loop.

You may also be interested in this post: How to avoid Google map geocode limit?.

Sagacious answered 20/11, 2014 at 21:59 Comment(1)
This looks "promising" (pun intended), I'm facing the same issue with a question I put a 250 rep bounty on: #36266942 Currently I'm not at my place where I have the code, but I'll give this a try. If you have a better alternative for my problem I'd love to hear about it.Arboriculture
S
-1

The one time I had this error it was because I was sending requests too quickly, put a wait for a second in there between each request.

Selfassurance answered 20/11, 2014 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.