提问人:acc_it 提问时间:3/17/2023 最后编辑:acc_it 更新时间:3/17/2023 访问量:35
JavaScript/JQuery - 对象属性值在循环访问它们时会发生变化
JavaScript/JQuery - Object property values are changing when looping through them
问:
我们正在尝试创建一种路由 (TSP) 算法,该算法遍历保存我们的车辆和行程信息的数据结构。
这一切都始于一个名为 acquireData 的 ASYNC 函数,该函数对我们自己的 API 进行 $.getJSON 调用,该 API 返回我们所有货车和行程以及所有(太多)信息的大型对象结构。这个异步函数循环遍历 API 对象返回,并用更少的数据构建一个全新的对象......
它返回新对象作为结果。
在底部,我们调用 async 函数,然后我们想在 .then() 中完成所有 TSP 求解。
在 .then() 中,我们记录 “data”(这是异步函数 acquireData() 返回的对象),一切看起来都很好。映像 aboce 是 console.log(data.trucks)。您可以看到所有 avilableAt 属性都有不同的日期/时间,除了那些没有旅行的属性。这是它应该的方式。到目前为止,一切都很好,数据完全符合我们的要求。
现在,我们开始遇到这个问题......
当我们尝试遍历此 data.trucks 时,availableAt 属性会失控。$.each(data.trucks, 函数(d, j){ 控制台.log(d, j.availableAt)})
一旦我们遍历它并显示 availableAt 属性,它们都会得到相同的日期/时间。比较两张图片,看看“Med 2”,你就会发现区别。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<title>Document</title>
</head>
<body>
<script>
function createDateObject(dateString, militaryTime) {
if (typeof dateString === "boolean" || typeof militaryTime === "boolean" || militaryTime == ""){
return "No Date"
} else {
const year = parseInt(dateString.slice(0, 4));
const month = parseInt(dateString.slice(5, 7)) - 1;
const day = parseInt(dateString.slice(8, 10));
const hours = parseInt(militaryTime);
const date = new Date(year, month, day, hours);
return date;
}
}
function formatCityState(city, state) {
const formattedCity = city.replace(/ /g, '+');
const formattedState = state.toUpperCase();
return `${formattedCity},${formattedState}`;
}
function addSeconds(date, seconds) {
var newDate = new Date(date.getTime() + seconds * 1000);
return newDate;
}
function isBefore(date1, date2) {
return date1.getTime() < date2.getTime();
}
function addHalfHourEvery4Hours(seconds) {
var hours = seconds / 3600; // convert to hours
var timeSlots = Math.floor(hours / 4); // calculate number of 4-hour time slots
var extraHours = timeSlots * 0.5; // calculate extra half-hours
var newHours = hours + extraHours; // add extra half-hours to original hours
var newSeconds = newHours * 3600; // convert back to seconds
return newSeconds;
}
const callGoogle = async(origin, destination) => {
const params = encodeURIComponent('&origins=' + origin + '&destinations=' + destination);
const grabData = await $.getJSON('no-cors.php?url=https://maps.googleapis.com/maps/api/distancematrix/json?' + params + '&key=xxxxxxx')
return grabData;
}
async function acquireData() {
const data = await new Promise((resolve, reject) => {
$.getJSON('https://xxxxxxxxxx/xxxxx.php', function(data) {
const newData = {
// employees: {},
trucks: {},
trips: [],
trips_unscheduled: []
};
$.each(data.trucks, function(j, k) {
const truckObj = {
trips: [],
standing_location: k.name_value_list.location_c.value
};
if (j.includes('Med') || j == "") {
if (k.trips) {
for (let i = 0; i < k.trips.length; i++) {
const tripDate = new Date(k.trips[i].name_value_list.transport_date_2_c.value);
const now = new Date();
const timeDiff = tripDate - now;
const diffInHours = timeDiff / (1000 * 3600);
const tripObj = {
trip_id: k.trips[i].name_value_list.trip_id_c.value,
dropoff_location: formatCityState(k.trips[i].name_value_list.arrival_city_c.value, k.trips[i].name_value_list.arrival_state_c.value),
pickup_location: formatCityState(k.trips[i].name_value_list.departure_city_c.value, k.trips[i].name_value_list.deprature_state_c.value),
pickup_time: createDateObject(k.trips[i].name_value_list.transport_date_2_c.value, k.trips[i].name_value_list.pick_up_time_c.value, k.trips[i].name_value_list.trip_id_c.value)
};
if (diffInHours > 48 && tripObj.pickup_time != "No Date") {
newData.trips.push(tripObj);
} else if (diffInHours < -45000 || tripObj.pickup_time == "No Date") {
newData.trips_unscheduled.push(tripObj)
} else {
truckObj.trips.push(tripObj);
}
}
//Generate availableAt for trucks with trips.
if (truckObj.trips.length > 0) {
var Corndogs = callGoogle(truckObj.trips[truckObj.trips.length - 1].pickup_location, truckObj.trips[truckObj.trips.length - 1].dropoff_location)
.then((data) => {
truckObj.availableAt = addSeconds(truckObj.trips[truckObj.trips.length - 1].pickup_time ,addHalfHourEvery4Hours(data.rows[0].elements[0].duration.value))
newData.trucks[j] = truckObj;
})
}
}
//Generate availableAt for trucks with no trips.
let t = new Date()
let tomorrow = new Date(t.setHours(t.getHours() + 24))
truckObj.availableAt = tomorrow
newData.trucks[j] = truckObj;
}
});
resolve(newData);
});
});
return data;
}
//now that we have our data built out the way we want it, we can loop through it and find the best truck for each trip.
//We will start by looping through each trip.
//Loop through each truck
//if truck availableAt is before pickup time that means this truck is a possibility for current trip
//calculate if the truck can make it to the trip pickup location in time
//if it can lets save the travel time and distance in a variable as well as the good truck
//loop through trips again and if there is a trip that is closer and has less sitting time lets replace
//continue looping through all the trucks ; everytime we find a truck that can make the trip but is less travel time and distance , save these details to the variable.
//Loop through each truck
//Loop through each trip
//if truck availableAt is before the tripPickUpTime then lets dive further
//calculate travel time and distance from trucks drop off and avaialbleAt
//if truck can make it in time
//lets save that distance and time spent sitting into a variable and save that truck
//continue to compare it to other trucks nd if we find a lower distance/time
//once we have looked through all the trucks
acquireData().then((data) => {
console.log(data)
$.each(data.trucks, function(d, j){
console.log(d, j.availableAt)
})
// console.log(data.trucks)
}).catch((error) => {
console.error(error);
});
</script>
</body>
</html>
答: 暂无答案
评论
if (k.trips)
if (k.trips.length > 0)