Javascript多异步设置间隔
我正试图编写代码,通过GPS跟踪大约100辆车的实时位置。我想通过设置谷歌地图标记在最后一个X/Y点和当前点之间的插值路径上的位置,为每辆车平滑地“设置”谷歌地图标记的动画。我每15秒通过setInterval调用一次URL来获取包含所有当前车辆位置的JSON对象。在里面,我迭代JSON对象中的每个车辆并设置车辆位置。我有设置运动动画的功能,但它只在一辆车上可靠地工作,我相信这是因为我嵌套的setInterval函数不会在它所包含的for循环的下一步之前完成。在for循环中的下一个“i”之前,是否需要运行内部setInterval函数以完成Javascript多异步设置间隔,javascript,asynchronous,setinterval,Javascript,Asynchronous,Setinterval,我正试图编写代码,通过GPS跟踪大约100辆车的实时位置。我想通过设置谷歌地图标记在最后一个X/Y点和当前点之间的插值路径上的位置,为每辆车平滑地“设置”谷歌地图标记的动画。我每15秒通过setInterval调用一次URL来获取包含所有当前车辆位置的JSON对象。在里面,我迭代JSON对象中的每个车辆并设置车辆位置。我有设置运动动画的功能,但它只在一辆车上可靠地工作,我相信这是因为我嵌套的setInterval函数不会在它所包含的for循环的下一步之前完成。在for循环中的下一个“i”之前,是
setInterval(function() {
$(document).ready(function() {
$.getJSON("http://localhost:8080/portal/frfeed/query/tampa_sw/paraVehicle?r=" + Math.random(),function(vehicles){
$.each(vehicles, function(index, d){
if(d.heading>=0 && d.heading<22.5) direction="NORTH";
else if(d.heading>=22.5 && d.heading<67.5) direction="NORTHEAST";
else if(d.heading>=67.5 && d.heading<112.5) direction="EAST";
else if(d.heading>=112.5 && d.heading<157.5) direction="SOUTHEAST";
else if(d.heading>=157.5 && d.heading<202.5) direction="SOUTH";
else if(d.heading>=202.5 && d.heading<247.5) direction="SOUTHWEST";
else if(d.heading>=247.5 && d.heading<292.5) direction="WEST";
else if(d.heading>=292.5 && d.heading<338) direction="NORTHWEST";
else direction="NORTH";
vehicle = "";
for (var i=0; i<vMarkers.length; i++) {
if( vMarkers[i][0] === d.internalVehicleId ) {
var path;
var latlng = new google.maps.LatLng(d.latitude,d.longitude);
vMarkers[i][2] = vMarkers[i][1].getPosition().lat();
vMarkers[i][3] = vMarkers[i][1].getPosition().lng();
vMarkers[i][4] = latlng;
vMarkers[i][1].setTitle('Vehicle: ' + d.internalVehicleId + '\r\n' + 'Last Update: ' + d.time + '\r\n' + 'Traveling: ' + direction + ' @ ' + d.speed + ' mph');
path = vPolys[i][1].getPath();
path.push(latlng);
vPolys[i][1].setPath(path);
vehicle = vMarkers[i][0];
var lat = vMarkers[i][2];
var lng = vMarkers[i][3];
var latlngTo = vMarkers[i][4];
var latLngFrom = new google.maps.LatLng(lat,lng);
j = 0;
// function below only works correctly if filtered for one vehicle as below, otherwise, all
// markers randomly move and don't stop due to the setInterval being called inside the for loop
if (distance(latlngTo.lat(), latlngTo.lng(),latLngFrom.lat(), latLngFrom.lng()) > 20 && vMarkers[i][0] == "1329") {
iv = window.setInterval(function() {
j++;
var pos = mercatorInterpolate(map, latLngFrom, latlngTo, j/50);
vMarkers[i][1].setPosition(pos);
if (j >= 50) {
window.clearInterval(iv);
}
}, 20);
}
else {
vMarkers[i][1].setPosition(latlngTo);
};
break;
}
}
if( vehicle == "") {
color = get_random_color();
marker = new StyledMarker({
styleIcon:new StyledIcon(StyledIconTypes.BUBBLE,{color:color, fore: "ffffff",text: d.internalVehicleId}),
position: new google.maps.LatLng(d.latitude,d.longitude),
title: 'Vehicle: ' + d.internalVehicleId + '\r\n' + 'Last Update: ' + d.time + '\r\n' + 'Traveling: ' + direction + ' @ ' + d.speed + ' mph',
map: map
});
var polyOptions = {
strokeColor: color,
strokeOpacity: 1.0,
map: map,
strokeWeight: 3
};
poly = new google.maps.Polyline(polyOptions);
var latlng = new google.maps.LatLng(d.latitude,d.longitude);
vMarkers.push([d.internalVehicleId, marker, d.latitude, d.longitude, latlng]);
var path = poly.getPath();
path.push(latlng);
poly.setPath(path);
vPolys.push([d.internalVehicleId, poly])
vehicle = "";
}
});//$.each(vehicles, function(index, d){
function mercatorInterpolate(map, latLngFrom, latLngTo, fraction) {
// Get projected points
var projection = map.getProjection();
var pointFrom = projection.fromLatLngToPoint(latLngFrom);
var pointTo = projection.fromLatLngToPoint(latLngTo);
// Adjust for lines that cross the 180 meridian
if (Math.abs(pointTo.x - pointFrom.x) > 128) {
if (pointTo.x > pointFrom.x)
pointTo.x -= 256;
else
pointTo.x += 256;
}
// Calculate point between
var x = pointFrom.x + (pointTo.x - pointFrom.x) * fraction;
var y = pointFrom.y + (pointTo.y - pointFrom.y) * fraction;
var pointBetween = new google.maps.Point(x, y);
// Project back to lat/lng
var latLngBetween = projection.fromPointToLatLng(pointBetween);
return latLngBetween;
}
function distance(lat1,lon1,lat2,lon2) {
var R = 6371;
var dLat = (lat2-lat1) * Math.PI / 180;
var dLon = (lon2-lon1) * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return Math.abs(d*1000);
}
}); //$.getJSON(...., function(vehicles) {
}); //$(document).ready(function() {
}, 16000); // setInterval(function(){
setInterval(函数(){
$(文档).ready(函数(){
$.getJSON(“http://localhost:8080/portal/frfeed/query/tampa_sw/paraVehicle?r=“+Math.random(),函数(车辆){
$。每个(车辆,功能(索引,d){
如果(d.heading>=0&&d.heading=22.5&&d.heading=67.5&&d.heading=112.5&&d.heading=157.5&&d.heading=202.5&&d.heading=247.5&&d.heading=292.5&&d.heading而不是尝试运行多个setInterval()
,则只运行一个,并在该函数调用中迭代所有车辆
例如:
iv = setInterval(function() {
for (int i=0; i<vehicleArray.length;i++) {
// Do stuff for each vehicle.
}
}, 40);
iv=setInterval(函数(){
对于(inti=0;iNo),setInterval是异步的。您必须以一种使用非同步代码的方式编程,而不是试图强制它同步
对于动画,您应该真正使用requestAnimationFrame
来获得平滑的结果
我会创建一个帧数组,每15秒推一个汽车数组,每个汽车存储它的位置
var frames = [[{x: 10, y:2},{x: 5, y:6}], [{x: 12, y:4},{x: 7, y:8}]]
然后,我将使用requestAnimationFrame
插值每辆车的当前位置
var currentFrame = 0;
var startTime = 0;
function update(){
var currentTime = newDate();
startTime || startTime = currentTime;
var elaspedTime = Math.floor(currentTime.getTime() - startTime.getTime())/1000;
// increment the current frame if 15 seconds have elapsed
elaspedTime%15 === 0 && currentFrame++;
// Get the current frame
var frame = frames[currentFrame],
nextFrame = frames[++currentFrame];
// Loop over each car in the frame
for(var i = 0; i < frame.length; i++){
// Calculate the difference in location
var xDiff = nextFrame[i].x - frame[i].x;
var yDiff = nextFrame[i].y - frame[i].y;
// interpolate the current position of the cars
var xPos = xDiff / elaspedTime%15;
var yPos = yDiff / elaspedTime%15;
// do some work here to set the position of the cars
}
requestAnimationFrame(update);
}
requestAnimationFrame(update);
var currentFrame=0;
var startTime=0;
函数更新(){
var currentTime=newDate();
开始时间| |开始时间=当前时间;
var elaspedTime=Math.floor(currentTime.getTime()-startTime.getTime())/1000;
//如果已过15秒,则增加当前帧
elaspedTime%15==0&¤tFrame++;
//获取当前帧
var frame=帧[currentFrame],
下一帧=帧[++当前帧];
//在车架中的每辆车上绕一圈
对于(变量i=0;i
你可以比我做的更好地优化它,但我会这样做