如果这不是正确的问题,请提前抱歉,请告诉我如何改进我的问题:)
基本上我有一个json文件,我想从(名称,地址等)中提取数据,以便使用Google Maps API函数将它们绘制为标记。这是我使用的当前ajax函数:
$.ajax({
url: 'directory.json',
dataType: 'json',
type: 'get',
cache: 'false',
success: function(data) {
$(data.group).each(function(index, person) {
if (typeof person.Address != "undefined") {
geocodeAddress(geocoder, map, person);
}
});
}
});
但是,这是同时为所有800多个目录条目调用geocodeAddress函数,这远远高于我的Maps API查询限制。我想将它们隔开约100毫秒以防止这种情况发生。我尝试使用setInterval来实现这一点,但似乎geocodeAddress行同时为所有条目运行,因此这只会延迟所有函数,而不是每个函数之间的长度。
我是否有另一种方法可以提取此json数据而不是使用ajax,或者只是一种方法来单独延迟每个API请求?
geocodeAddress函数供参考(它既包含地理编码,也包括绘图标记)
function geocodeAddress(geocoder, resultsMap, person) {
//geocoding address
geocoder.geocode({'address': person.Address[0].text}, function(results, status) {
if (status === 'OK') {
//plotting coordinate as marker
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location,
icon: {
url: person.Image[0].src,
size: new google.maps.Size(120, 150),
scaledSize: new google.maps.Size(30, 38),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(15, 19)
}
});
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
});
}
答案 0 :(得分:1)
您可以使用如下所示的100毫秒间隔时间循环geocodeAddress
来电,
$.ajax({
url: 'directory.json',
dataType: 'json',
type: 'get',
cache: 'false',
success: function(data) {
var i = 0;
var loop = function(){
if(i < data.group.length){
if (typeof data.group[i].Address != "undefined")
geocodeAddress(geocoder, map, data.group[i]);
i++;
setTimeout(loop, 100);
}
}
loop();
}
});
希望它有所帮助。
答案 1 :(得分:0)
您可以使用IIFE中的setTimeout
为数组迭代添加延迟:
$.ajax({
url: 'directory.json',
dataType: 'json',
type: 'get',
cache: 'false',
success: function(data) {
//Invoke delayLoop with initial params - i = 0, delay = 100ms
(delayLoop)(0, data.group, 100, geocodePerson);
}
});
//Function to perform delayed iteration function on array elements
function delayLoop (i, list, interval, itemFunc) {
setTimeout(function() {
itemFunc(list[i]);
if (++i < list.length) {
delayLoop(i, list, interval, itemFunc);
}
}, interval)
}
//function to perform on array elements
function geocodePerson(person) {
if (typeof person.Address != "undefined") {
geocodeAddress(geocoder, map, person);
}
}
答案 2 :(得分:0)
使用geocodeAddress函数的一个mod,添加一个可选的回调
function geocodeAddress(geocoder, resultsMap, person, callback) {
//geocoding address
geocoder.geocode({
'address': person.Address[0].text
}, function(results, status) {
if (status === 'OK') {
//plotting coordinate as marker
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location,
icon: {
url: person.Image[0].src,
size: new google.maps.Size(120, 150),
scaledSize: new google.maps.Size(30, 38),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(15, 19)
}
});
} else {
console.log("Geocode was not successful for the following reason: " + status);
}
if (typeof callback == 'function') {
callback();
}
});
}
并且,为了进行最小的更改,为geocodeAddress添加一个返回Promise的包装函数
function geocodeAddressPromise(geocoder, resultsMap, person) {
return new Promise(function(resolve) {
geocodeAddress(geocoder, resultsMap, person, resolve);
};
}
您的主要代码可以写成:
$.ajax({
url: 'directory.json',
dataType: 'json',
type: 'get',
cache: 'false'
}).then(function(data) {
return data.group.filter(function(person) {
return typeof person.Address != "undefined";
}).reduce(function(promise, person) {
return promise.then(function() {
return geocodeAddressPromise(geocoder, map, person);
}).then(function() {
return new Promise(function(resolve) {
setTimeout(resolve, 100);
});
});
}, Promise.resolve());
});
它使用.filter只包含地址
的人和一个相当常见的.reduce模式,依次链接Promises,在一个地址的分辨率和下一个地理编码调用的开始之间增加100ms的超时