2015-10-16 97 views
2

我想从json文件(包含对象的json数组)中将一些数据导入mongodb,使用猫鼬。当路线'/ import'被调用时,我通过“require”加载文件并开始迭代。Nodejs在回调函数中关闭和res对象

router.get('/import', function (req, res) { 
    var data = require('../import/1.json'); 
    nTotal = data.length; 
    for (var i = 0; i < nAppCount; i++) { 
    var obj = new MyObject(data[i]); 
    obj.save(check); 
    } 
}); 

由于JSHint警告我不要“做一个循环内的功能”,我创建了函数调用检查如下:

function check (err,doc){ 
    nProcessed++; 
    if (err) { 
    logger.log('error', err.message, err.errors); 
    } else { 
    logger.log('debug', "%d of %d processed",nProcessed, nTotal); 
    if (nProcessed===nTotal) { 
     res.render('index'); 
    } 
    } 
} 

一切正常,直到结束,但是当我得到的所有对象都是:

ReferenceError: res is not defined

是不是“检查”应该“知道”res变量是一个闭包函数吗?我将如何访问“res”?

注意:如果我忽略js提示警告,我可以使其工作。

+0

将'check()'的声明放在传递给'router.get()'的回调函数的顶部。 – Pointy

+2

事实上,你必须处于相同的(功能)范围内才能捕捉到关闭。请参阅[JavaScript关闭如何工作?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work)。 – leesei

+0

是'nAppCount'应该是'nTotal'吗?如果是这样,如果'data'是一个数组,则正确的方法是使用forEach循环,从而完全避免这个问题。我倾向于避免一起使用for循环,转而创建自己的范围以避免任何var泄漏的功能方法。 –

回答

3

这里要理解的主要问题是,在函数的创建过程中,变量并没有在调用函数期间被包含。

在你的情况下,当功能check创建时,它不包含resreq。所以,即使你从其他函数调用它,它也不会意识到它们。

要解决此问题,您可以简单地在router.getfor循环之前定义check函数。例如,

router.get('/import', function (req, res) { 
    ... 

    function check(err, doc) { 
    ... 
    } 

    for (var i = 0; i < nAppCount; i++) { 
    (new MyObject(data[i])).save(check); 
    } 

});