回调函数中的Nodejs闭包和res对象[重复]

Posted

技术标签:

【中文标题】回调函数中的Nodejs闭包和res对象[重复]【英文标题】:Nodejs closures and res object in a callback function [duplicate] 【发布时间】:2016-01-15 14:10:16 【问题描述】:

我想使用 mongoose 将 json 文件(包含 json 对象数组)中的一些数据导入 mongodb。当路由 '/import' 被调用时,我通过“require”加载文件并开始迭代。

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 警告我不要“在循环中创建函数”,因此我创建了名为 check 的函数,如下所示:

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 没有定义

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

注意:如果我忽略 jsHint 警告,我可以让它工作。

【问题讨论】:

check() 的声明放在要传递给router.get() 的回调函数的顶部。 确实,您必须在相同(功能)范围内才能捕获闭包。见How do javascript closures work?。 nAppCount 应该是nTotal?如果是这样,如果data 是一个数组,那么正确的方法是使用forEach 循环,从而完全避免这个问题。我倾向于避免一起使用 for 循环,而是使用创建自己的范围以避免任何 var 泄漏的函数方法。 函数check实际定义在哪里? 是的,“检查”是在外面定义的!那是个错误。 【参考方案1】:

这里要理解的主要是,变量是在函数创建期间而不是在函数调用期间封闭的。

在您的情况下,创建函数 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);
  

);

【讨论】:

以上是关于回调函数中的Nodejs闭包和res对象[重复]的主要内容,如果未能解决你的问题,请参考以下文章

了解NodeJS中的回调函数

避免 nodeJs 中的回调地狱/将变量传递给内部函数

js中的闭包之我理解

使用回调和函数作为go中的类型

在 Express JS 和 NodeJS 中为 jsonp 回调函数添加参数

利用闭包向post回调函数传参数