【问题标题】:How to re-run a javascript promise when failed?失败时如何重新运行javascript承诺?
【发布时间】:2014-11-20 15:35:44
【问题描述】:

我有以下代码,我尝试使用 Google Maps Geocoding API 将 businesses 数组中的 10-15 个地址列表转换为 lat/lng 坐标。

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);

问题是 Google 的 API 有时会返回 OVER_QUERY_LIMIT 错误,所以我想知道是否有办法重新运行几秒钟后失败的承诺。在上面的示例中,else if 语句捕获了错误,那么如何让它在超时后重新运行?

请注意,我刚刚开始使用 Promise,还没有很好地理解它们是如何工作的,所以我的方法可能完全错误。此外,所有这些都是在假设 Google 的 API 不允许我批量解析地址的情况下完成的,如果不是这样 - 请告诉我。

【问题讨论】:

    标签: javascript promise google-geocoding-api


    【解决方案1】:

    您可以将代码主体放入一个函数中,然后从计时器中再次调用它。注意:从技术上讲,这并不是重新运行承诺,而是重新运行一段代码,然后在完成后解决承诺:

    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);
    

    仅供参考,我还添加了重试计数,这样代码就不会陷入错误循环。

    您可能也对此帖子感兴趣:How to avoid Google map geocode limit?

    【讨论】:

    • 这看起来“很有希望”(双关语),我面临同样的问题,我提出了一个 250 代表赏金的问题:stackoverflow.com/questions/36266442/… 目前我不在我的位置代码,但我会试一试。如果您对我的问题有更好的选择,我很想听听。
    【解决方案2】:

    有一次我遇到这个错误是因为我发送请求太快了,在每个请求之间等待一秒钟。

    【讨论】:

      猜你喜欢
      • 2019-02-15
      • 2015-01-08
      • 1970-01-01
      • 2012-06-28
      • 1970-01-01
      • 2015-07-23
      • 2019-08-20
      • 1970-01-01
      • 2017-11-01
      相关资源
      最近更新 更多