简体   繁体   English

失败时如何重新运行JavaScript Promise?

[英]How to re-run a javascript promise when failed?

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. 我有以下代码,其中我尝试使用Google Maps Geocoding API将businesses数组中的10-15个地址列表转换为经纬度坐标。

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. 问题是Google的API有时会返回OVER_QUERY_LIMIT错误,所以我想知道是否有办法重新运行在几秒钟后失败的承诺。 In the example above the else if statement catches the error, so how would I make it rerun after a timeout? 在上面的示例中, else if语句捕获了错误,因此如何使它在超时后重新运行?

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. 请注意,我刚刚开始使用Promise,但对它们的工作方式还没有很好的了解,因此我的方法可能是完全错误的。 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. 同样,所有这些操作都是在Google的API不会让我批量解析地址的前提下完成的,如果不是这种情况,请告诉我。

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: 注意:从技术上讲,这不是在重新运行Promise,而是在重新运行代码块,然后在完成时将解析Promise:

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? 您可能对此帖子也感兴趣: 如何避免Google地图地理编码限制? .

我有一次出现此错误的原因是因为我发送请求的速度太快,因此在每个请求之间都需要等待一秒钟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM