javascript - 异步,回调,关闭,哦,我的

标签 javascript mongodb dom asynchronous

这是我正在尝试做的事情,但在以下方面惨败:

我有一个 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/

相关文章:

api - REST:处理计算的和相关的资源属性

javascript - 从按钮属性中选择自定义标签

javascript - 如何在不中断同一插件的其他实例的情况下取消订阅事件?

javascript - 为什么我的清除功能不起作用?

javascript - 如何突出显示新添加的表格行?

java - Spring Data - MongoDb - 如果我更新同一文档两次会发生什么

jquery - 在 jQuery 中获取元素

javascript - 如何仅注销我的 FB 应用程序而不是我的 Facebook 帐户?

javascript - 同步 XHR 弃用

mongodb - 1亿份文件是不是太多了?