mongoose findone回调范围(NodeJS,express)

时间:2012-02-23 23:50:12

标签: json node.js mongodb

我正在尝试从外部JSON提要中抓取数据并将其存储在我的mongoDB中。

request(url, function (error, response, body) {
    if (!error && response.statusCode == 200) {
        var jsonObj = JSON.parse(body);
        // console.log(jsonObj.events[1].id) <-- this works
        for (var i = 0; i < jsonObj.events.length; i++) { 
            // add jsonObj.events[i] as a new record to table
            // console.log(jsonObj.events[i].id) <-- this works
            Wnet.findOne({ id : jsonObj.events[i].id }, function (err, doc){
                if (err || doc == null) {
                     // console.log(jsonObj.events[i].id) <-- this doesn't work!
                     // record is new, add it
                }
            });
         }
     }
});

注意console.log语句...最后一个语句(在.findOne的回调中)不起作用。

我还在学习JavaScript的来龙去脉,但我相信这是一个范围问题......回调函数不知道jsonObj。但是,我不知道如何将它传递给函数。

退后一步,我正在尝试检查收集是否存在记录。如果找不到它,我想从获取的JSON数组中添加记录。如果有更好的方法,我会很乐意帮助您找到它。

1 个答案:

答案 0 :(得分:2)

这不是范围问题。就范围而言,它将通过冒泡来寻找变量。所以在findOne中它有变量jsonObj。它会冒泡到上面的var jsonObj = ...

我相信您的问题是,您正在循环jsonObj.events并为每个findOne解雇jsonObj.events[i].id。然后,您尝试在每个findOne回调中控制i。问题是您的i >= jsonObj.events.length每次都会增加。实际上会在i时结束。因此,如果长度为9,那么当循环退出时findOne将最终为10。所以你的日志记录将不起作用。 编辑:为了澄清,日志记录将无法正常工作,因为在循环内所有events都将触发,但回调不会立即发生。因为回调是异步的。因此,当回调发生时,循环可能已完成,并且它将尝试记录不存在的request(url, function (error, response, body) { if (!error && response.statusCode == 200) { var jsonObj = JSON.parse(body); //console.log(jsonObj.events[1].id) <-- this works for (var i = 0; i < jsonObj.events.length; i++) { // add jsonObj.events[i] as a new record to table //console.log(jsonObj.events[i].id) <-- this works Wnet.findOne({ id : jsonObj.events[i].id }, function (err, doc){ if (err || doc == null) { console.log(jsonObj.events[this].id); //record is new, add it } }.bind(i)); } } });

试试这个:

bind

这只是处理它的一种方式。如果 request(url, function (error, response, body) { if (!error && response.statusCode == 200) { var jsonObj = JSON.parse(body); //console.log(jsonObj.events[1].id) <-- this works for (var i = 0; i < jsonObj.events.length; i++) { // add jsonObj.events[i] as a new record to table //console.log(jsonObj.events[i].id) <-- this works doFindOne(jsonObj.events, i); } } }); function doFindOne(events, i) { Wnet.findOne({ id : events[i].id }, function (err, doc){ if (err || doc == null) { console.log(events[i].id); //record is new, add it } }); } 令人困惑,那么尝试一种不同的方式。你也可以这样做:

i

在第二个例子中,我们调用一个函数,它将{{1}}保持在该调用的范围内。这可能更有意义。 (绑定往往比混淆更容易混淆)