这是我正在尝试做的事情,但在以下方面惨败:
我有一个 MongoDB,里面装满了连接到汽车的设备的 GPS 读数。读数带有时间戳并具有纬度/经度。
对于每次阅读,我想创建一个包含位置、时间戳和其他一些信息的 Position 类。
为了在 Google map 上绘制它,我想创建一个 Route 类,它由一组 Positions 对象组成。
顶部的主要函数从示例 JSON 文件加载路由(以避免 CSRF 问题……另一个故事),创建 Position 对象和路由对象。当我尝试绘制路线时,问题就开始了。
var positions = this.getPositions();
如果我输入
console.log(positions);
在那行的正下方,它会打印位置数组。这样做需要一点时间,因为它很大,但它确实有效。
如果我输入
console.log(positions[0]);
它不会工作,因为位置还没有加载。
我该怎么办?
我正在使用来自 http://classy.pocoo.org 的 classy.js但我已经证实这不是问题。
function main()
{
var route = Route('20120928_025650_0');
route.plot();
}
var Route = Class.$extend({
__init__ : function(imaging_run_id) {
this.imaging_run_id = imaging_run_id;
this.positions = [];
this.load();
},
getPositions : function() {
return (this.positions);
},
load : function() {
//var url='http://localhost:5001/gps/by_imaging_run_id/' + this.imaging_run_id;
var test_url = '/static/20120928_025650_0.json';
var me = this;
$.getJSON(test_url, function(route) {
for(var position in route) {
var obj = route[position];
var new_position = Position(obj['_id'], obj['lat'], obj['lng'], obj['timestamp'], obj['epoch_timestamp'], obj['is_valid']);
me.pushPositions(new_position);
}
me.orderPositions();
})
.error(function(jqXhr, textStatus, error) {
alert("ERROR: " + textStatus + ", " + error);
});
},
orderPositions : function() {
var unsorted_array = this.getPositions();
var sorted = unsorted_array.sort(function(a,b){ //Custom sort function
return a['timestamp'] - b['timestamp']; //Sort ascending
});
this.setPositions(sorted);
},
plot : function() {
var positions = this.getPositions();
var points = [];
var bounds = new google.maps.LatLngBounds();
for(var i=0; i<positions.length; i++)
{
var obj = positions[i];
var point = new google.maps.LatLng(obj['location'][0], obj['location'][1]);
points.push(point);
bounds.extend(point);
}
// Create the polyline.
var route = new google.maps.Polyline({
path: points,
strokeColor: '#e81971',
strokeOpacity: 1.0,
strokeWeight: 4
});
map.fitBounds(bounds);
route.setMap(map);
}
});
var Position = Class.$extend({
__init__ : function(id, lat, lng, timestamp, epoch_timestamp, valid) {
this.id = id;
this.location = [lat, lng];
this.timestamp = new Date(timestamp);
this.epoch_timestamp = new Date(epoch_timestamp);
this.valid = valid;
this.anchor_location;
},.....
最佳答案
如果我理解正确的话,你会想做这样的事情:
var positions = this.getPositions(function(positions) {
console.log(positions[0]);
});
也就是说,您将希望以一种接受单个回调参数的方式编写“getPositions”,该参数在位置成功加载后调用,并传递给位置数组。在 getPositions
中,您可以检查位置是否已加载,如果已加载,则直接调用回调。否则,您会将它们添加到回调队列(例如 this.positionsLoadedCallbacks
),在加载所有位置后通过它进行迭代(我认为这将在您的load
me.orderPositions()
附近的函数。
例如,您的 getPositions
函数可能如下所示:
getPositions : function(callback) {
if(this.positions !== null) {
callback(this.positions);
return;
}
this.positionsLoadedCallbacks.push(callback);
},
在确定位置已加载后的某处(即在 loadJSON 成功回调中),您需要放置如下内容:
for(var i=0; i < this.positionsLoadedCallbacks.length; i++) {
this.positionsLoadedCallbacks[i](this.positions);
}
并且不要忘记初始化 this.positionsLoadedCallbacks
:)
console.log 琐事
console.log(positions)
有效而 console.log(positions[0])
无效的原因很简单:如果将对象引用传递给 console.log
,当您单击“展开”小箭头并尝试查看对象/数组内部时,将检查该对象。当您单击该箭头时,位置当然已经加载。但是,如果您传递一个特定的数组元素(例如 positions[0]
),它会直接尝试查找该值,发现它仍然是 undefined
,并记录下来结果在控制台中。
自己试试:
var i = [];
console.log([i]);
i.push(123);
前面的代码片段,在 chrome 24 中,在控制台中显示 [Array[0]]
,但是当我展开它时,它告诉我数组为 length: 1
并且它的第一个元素是 123
关于javascript - 异步,回调,关闭,哦,我的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13020997/