4

这就是我正在尝试做的事情,但惨遭失败:

我有一个 MongoDB,里面装满了来自连接到汽车的设备的 GPS 读数。读数带有时间戳并具有纬度/经度。

对于每个读数,我想创建一个包含位置、时间戳和其他一些信息的 Position 类。

为了在 Google 地图上绘制它,我想创建一个 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;
    },.....
4

1 回答 1

3

如果我理解正确,你会想要做这样的事情:

var positions = this.getPositions(function(positions) {
    console.log(positions[0]);
});

也就是说,您需要以这样一种方式编写“getPositions”,即它接受一个回调参数,一旦位置成功加载,就会调用该参数,并传递给位置数组。getPositions你可以检查位置是否已经加载,如果是,直接调用回调。否则,您会将它们添加到回调队列(例如this.positionsLoadedCallbacks),在加载所有位置后通过该队列进行迭代(我认为这将在您的load函数中的某个位置 near 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]]在控制台中,但是当我展开它时,它告诉我数组 aslength: 1并且它的第一个元素是123

于 2012-10-22T22:47:52.800 回答