[英]How can I escape $.each loop with my data?
I'm doing an Json call to retrieve an a list of locations with information details for each location. 我正在执行Json调用以检索位置列表,其中包含每个位置的信息详细信息。 longitude and latitude are included in this info.
经度和纬度包含在此信息中。
I am using Google's distance matrix api to get the distance from coordinates provided as a query in the url. 我正在使用Google的距离矩阵api从网址中作为查询提供的坐标获取距离。
I thought the most logical way to do this would be to loop through the locations and compare searched and location coordinates per location. 我认为最合乎逻辑的方法是遍历位置,并比较每个位置的搜索坐标和位置坐标。 I am appending some of the info returned from the distance matrix calls onto my data array.
我将距离矩阵调用返回的一些信息附加到我的数据数组中。
This works fine except the data returned from the distance matrix is only usable within the return function for the distance matrix. 除从距离矩阵返回的数据仅可在距离矩阵的返回函数中使用之外,此方法工作正常。 I pass the wanted data from the distance matrix return function into a function outside the matrix return function but still inside the $.each loop.
我将所需的数据从距离矩阵返回函数传递到矩阵返回函数之外但仍在$ .each循环内的函数中。 This seamed like a step towards solving my problem but I'm stuck.
这就像是迈向解决我的问题的一步,但我陷入了困境。
I need to use the original data but with the distance matrix data appended so that I can sort the items in the data by distance and output it. 我需要使用原始数据,但要附加距离矩阵数据,以便可以按距离对数据中的项目进行排序并输出。 I don't think a sort function would work well inside of the $.each loop so I need to break out of the loop with the appended version of the data intact.
我认为$ .each循环内的排序功能无法正常工作,因此我需要使用完整的数据附加版本打破循环。 at least I think.
至少我认为。 any help would be appreciated.
任何帮助,将不胜感激。
var ltlg = [];
var sLat = parseFloat(35.2219971);
var sLng = parseFloat(-101.83129689999998);
var sLatLng = {lat: sLat, lng: sLng};
var locLat;
var locLng;
var locLatLng = [];
$.getJSON("file.json",function(data){
if(sLat && sLng) {
$.each(data, function(x, y){
locLat = data[x].Address.Location.Latitude;
locLng = data[x].Address.Location.Longitude;
//locLatLng.push({lat: locLat, lng: locLng});
var service = new google.maps.DistanceMatrixService;
service.getDistanceMatrix({
origins: [sLatLng],
destinations: [{lat: locLat, lng: locLng}],
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, function(response, status) {
if (status !== 'OK') {
console.log('status is ' + status);
} else {
var distance = response.rows[0].elements[0].distance.value;
var miles = response.rows[0].elements[0].distance.text;
var time = response.rows[0].elements[0].duration.text;
addData(distance, miles, time);
}
});
function addData(distance, miles, time) {
data[x]["distance"] = distance;
data[x]["miles"] = miles;
data[x]["time"] = time;
}
});
console.log(JSON.stringify(data));
} else {
console.log('no query');
}
});
I replaced the query variables with static lat lng for the snippet. 我用片段的静态lat lng替换了查询变量。
You may want to implement a global callback, sth like: 您可能要实现全局回调,例如:
function loaddata(callback){
var counter=0;
data.forEach(function(y,x){
//get data
function addData(distance, miles, time) {
data[x]["distance"] = distance;
data[x]["miles"] = miles;
data[x]["time"] = time;
if(++counter==data.length){
callback(data);
}
}
});
}
So you can do: 因此,您可以执行以下操作:
loaddata(function(data){
console.log(data);
});
Data now contains distance,miles and time. 数据现在包含距离,英里和时间。
The answer that @Jonasw has provided is unnecessarily complicated, and because a new addData()
is declared for every single iteration, and a completely pointless counter
is initialized, this consumes a lot of memory that can be conserved with a smarter approach. @Jonasw提供的答案不必要地复杂,并且因为每次迭代都会声明一个新的
addData()
,并且会初始化一个完全无意义的counter
,所以这会消耗大量内存,而采用一种更聪明的方法可以节省内存。 Since you have asynchronous callbacks for every data point, and you want to depend on all of them completing, the approach that makes the most sense would utilize Promise.all()
: 由于每个数据点都有异步回调,并且您希望依赖于它们的完成,因此最有意义的方法是利用
Promise.all()
:
var sLat = 35.2219971;
var sLng = -101.83129689999998;
var sLatLng = {
lat: sLat,
lng: sLng
};
var service = new google.maps.DistanceMatrixService;
function serviceCallback(value, resolve, response, status) {
if (status !== 'OK') {
console.log('status is ' + status);
reject(status);
} else {
value.distance = response.rows[0].elements[0].distance.value;
value.miles = response.rows[0].elements[0].distance.text;
value.time = response.rows[0].elements[0].duration.text;
resolve(value);
}
}
function promiseExecutor(value, resolve, reject) {
service.getDistanceMatrix({
origins: [sLatLng],
destinations: [{
lat: value.Address.Location.Latitude,
lng: value.Address.Location.Longitude
}],
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, serviceCallback.bind(null, value, resolve));
}
$.getJSON("file.json", function (data) {
if (![sLat, sLng].some(isNaN)) {
Promise.all(data.map(function (value) {
return new Promise(promiseExecutor.bind(null, value));
})).then(function (data) {
console.log(JSON.stringify(data, null, 2));
});
} else {
console.log('no query');
}
});
However, I see you are making a request for each individual data point when you are able to make one for every single data point at once, so to save even more resources, you can try something like this: 但是,我看到当您能够一次为每个数据点发出一个请求时,您正在对每个数据点发出请求,因此,要节省更多资源,可以尝试执行以下操作:
var sLat = 35.2219971;
var sLng = -101.83129689999998;
var sLatLng = {
lat: sLat,
lng: sLng
};
var service = new google.maps.DistanceMatrixService;
$.getJSON("file.json", function (data) {
if (![sLat, sLng].some(isNaN)) {
service.getDistanceMatrix({
origins: [sLatLng],
destinations: data.map(function (value) {
return {
lat: value.Address.Location.Latitude,
lng: value.Address.Location.Longitude
};
}),
travelMode: 'DRIVING',
unitSystem: google.maps.UnitSystem.IMPERIAL,
avoidHighways: false,
avoidTolls: false
}, function (response, status) {
if (status !== 'OK') {
console.log('status is ' + status);
} else {
response.rows[0].elements.forEach(function (element, index) {
if (element.status === 'OK') {
data[index].distance = element.distance.value;
data[index].miles = element.distance.text;
data[index].time = element.duration.text;
}
});
console.log(JSON.stringify(data, null, 2));
}
});
} else {
console.log('no query');
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.