Как повторно запустить обещание JavaScript, если не удалось?
У меня есть следующий код, где я пытаюсь преобразовать список из 10-15 адресов в businesses
Массив в координаты широты / долготы с помощью API геокодирования Карт Google.
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);
Проблема в том, что API Google иногда возвращает OVER_QUERY_LIMIT
ошибка, поэтому мне было интересно, есть ли способ повторно выполнить обещание, которое не удалось через несколько секунд. В приведенном выше примере else if
оператор ловит ошибку, так как мне сделать, чтобы он был выполнен повторно после истечения времени ожидания?
Обратите внимание, что я только начал использовать обещания и еще не очень хорошо понимаю, как они работают, поэтому мой подход может быть совершенно неверным. Кроме того, все это делается при условии, что API Google не позволит мне разрешать массовые адреса, если это не так - пожалуйста, дайте мне знать.
2 ответа
Вы можете поместить основную часть кода в функцию и снова вызывать ее из таймера. Примечание: технически это не повторный запуск обещания, это повторный запуск блока кода, который затем разрешит обещание, когда будет выполнено:
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);
К вашему сведению, я также добавил количество повторов, чтобы код никогда не мог застрять в цикле ошибок.
Вы также можете быть заинтересованы в этом сообщении: Как избежать ограничения геокодирования карты Google?,
Однажды у меня возникла эта ошибка, потому что я отправлял запросы слишком быстро, и между каждым запросом оставалось секундное ожидание.