Node.js 为什么我在NodeJS+;MongoDB?

Node.js 为什么我在NodeJS+;MongoDB?,node.js,mongoose,Node.js,Mongoose,是的,这是一个经典的范围界定问题。调用findOne中的回调时,i已经是数组的最后一个索引。但是函数会创建一个单独的作用域(与代码块不同),因此请尝试以下方法: function getBlocks(docs){ var jsonResults = docs; jsonResults.forEach(function(doc, i){ console.log(doc); database.Block.findOne({brand_id: docs[

是的,这是一个经典的范围界定问题。调用
findOne
中的回调时,i已经是数组的最后一个索引。但是函数会创建一个单独的作用域(与代码块不同),因此请尝试以下方法:

function getBlocks(docs){
    var jsonResults = docs;
    jsonResults.forEach(function(doc, i){
        console.log(doc);
        database.Block.findOne({brand_id: docs[i]._brand[0]['_id'], timestamp: {$lte: new Date()}}, function(error, results){

            jsonResults[i]['test'] = results;
            console.log(jsonResults[i]['test']); //Has array test. Previous line worked.

        });
    });
    res.json(jsonResults); //Outputs unchanged array.
}
编辑另一个问题有点不同。这是一个同步的问题。您必须等待所有异步作业完成它们所做的工作,然后继续。看一看。这是一个非常好的库,它将帮助您以简洁的方式实现这一点。您可以在自己的计算机上实现此机制。试着这样做:

function getBlocks(docs){
    var jsonResults = docs;
    jsonResults.forEach(function(doc, i) {
        console.log(doc); //Proper result
        database.Block.findOne({brand_id: doc._brand[0]['_id'], timestamp: {$lte: new Date()}}, function(error, results){
            console.log(doc);
            console.log(i);
            res.json(jsonResults);
        });
    });
}

我如何保持我的价值?顺便说一句,你的代码工作正常,把我推向了正确的方向。你说的“保留i的值”是什么意思?@user1426594我已经更新了代码。请注意,
.forEach
不是异步的,但是
.findOne
是异步的。同步异步作业可能会很棘手,我建议大家看看async.js(文章中的链接),尤其是
async.parallel
function getBlocks(docs){
    var jsonResults = docs;
    jsonResults.forEach(function(doc, i) {
        console.log(doc); //Proper result
        database.Block.findOne({brand_id: doc._brand[0]['_id'], timestamp: {$lte: new Date()}}, function(error, results){
            console.log(doc);
            console.log(i);
            res.json(jsonResults);
        });
    });
}
function getBlocks(docs){
    var jsonResults = docs,
        jobs = [];

    var finalize = function() {
        // here goes the final code
        res.json(jsonResults); //Outputs unchanged array.
    };

    jsonResults.forEach(function(doc, i){
        jobs.push(i); // add current job to the pool
        console.log(doc);
        database.Block.findOne({brand_id: docs[i]._brand[0]['_id'], timestamp: {$lte: new Date()}}, function(error, results){

            jsonResults[i]['test'] = results;
            console.log(jsonResults[i]['test']); //Has array test. Previous line worked.

            // remove current job from the pool
            var idx = jobs.indexOf(i);
            if (idx != -1) {
                jobs.splice(idx, 1);
            }
            // if no more jobs then finalize
            if (typeof jobs[0] === "undefined") {
                finalize();
            }
        });
    });
}