РЕДАГУВАТИ:
Забув сказати, що це рішення в чистому js, єдине, що вам потрібно, це браузер, який підтримує обіцянки https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Promise
Для тих, кому ще потрібно виконати таке, я написав власне рішення, яке поєднує обіцянки та тайм-аути.
Код:
var Geolocalizer = function () {
this.queue = [];
this.resolved = [];
this.geolocalizer = new google.maps.Geocoder();
};
Geolocalizer.prototype = {
Localize: function ( needles ) {
var that = this;
for ( var i = 0; i < needles.length; i++ ) {
this.queue.push(needles[i]);
}
return new Promise (
function (resolve, reject) {
that.resolveQueueElements().then(function(resolved){
resolve(resolved);
that.queue = [];
that.resolved = [];
});
}
);
},
resolveQueueElements: function (callback) {
var that = this;
return new Promise(
function(resolve, reject) {
(function loopWithDelay(such, queue, i){
console.log("Attempting the resolution of " +queue[i-1]);
setTimeout(function(){
such.find(queue[i-1], function(res){
such.resolved.push(res);
});
if (--i) {
loopWithDelay(such,queue,i);
}
}, 1000);
})(that, that.queue, that.queue.length);
var it = setInterval(function(){
if (that.queue.length == that.resolved.length) {
resolve(that.resolved);
clearInterval(it);
}
}, 1000);
}
);
},
find: function (s, callback) {
this.geolocalizer.geocode({
"address": s
}, function(res, status){
if (status == google.maps.GeocoderStatus.OK) {
var r = {
originalString: s,
lat: res[0].geometry.location.lat(),
lng: res[0].geometry.location.lng()
};
callback(r);
}
else {
callback(undefined);
console.log(status);
console.log("could not locate " + s);
}
});
}
};
Зверніть увагу, що це лише частина більшої бібліотеки, яку я написав для обробки матеріалів Google Maps, отже, коментарі можуть заплутати.
Використання досить просте, проте підхід дещо інший: замість циклу та вирішення однієї адреси за раз вам потрібно буде передати масив адрес класу, і він сам оброблятиме пошук, повертаючи обіцянку, яка , коли вирішено, повертає масив, що містить всю вирішену (і невирішену) адресу.
Приклад:
var myAmazingGeo = new Geolocalizer();
var locations = ["Italy","California","Dragons are thugs...","China","Georgia"];
myAmazingGeo.Localize(locations).then(function(res){
console.log(res);
});
Вихід консолі:
Attempting the resolution of Georgia
Attempting the resolution of China
Attempting the resolution of Dragons are thugs...
Attempting the resolution of California
ZERO_RESULTS
could not locate Dragons are thugs...
Attempting the resolution of Italy
Об'єкт повернено:
Тут відбувається вся магія:
(function loopWithDelay(such, queue, i){
console.log("Attempting the resolution of " +queue[i-1]);
setTimeout(function(){
such.find(queue[i-1], function(res){
such.resolved.push(res);
});
if (--i) {
loopWithDelay(such,queue,i);
}
}, 750);
})(that, that.queue, that.queue.length);
В основному, він циклічно повторює кожен елемент із затримкою в 750 мілісекунд між кожним з них, отже, кожні 750 мілісекунд управляється адресою.
Я зробив кілька подальших тестувань і виявив, що навіть через 700 мілісекунд іноді отримував помилку QUERY_LIMIT, тоді як із 750 у мене взагалі не було жодної проблеми.
У будь-якому випадку, не соромтеся редагувати 750 вище, якщо ви відчуваєте, що перебуваєте в безпеці, справляючись із меншою затримкою.
Сподіваюся, це допоможе комусь найближчим часом;)