【问题标题】:Node.js Javascript Scope IssueNode.js Javascript 范围问题
【发布时间】:2013-03-23 22:12:30
【问题描述】:

我有一个 Node.js HTTP 服务器正在运行,如下所示(简化):

http = require('http');
help = require('./modules/help').run;
router = require('./modules/router').run;
m = {something: require('./modules/something')};

var server = http.createServer(router).listen(8001);

“help”是一组functions-helpers,例如:

module.exports.run = {
  joinObjects: function(obj1, obj2) {
    for (var prop in obj2) {
       obj1[prop] = obj2[prop];
    }
    return obj1;
  }
}

“路由器”处理请求(进一步向下传递并处理对客户端的响应):

module.exports.run = function(req, res) {

  var urlPath = url.parse(req.url).pathname;

  switch(urlPath) {
    case '/something':
      requestHandler(req, res, 'something');
      break;
    ...
  }

  function requestHandler(req, res, handler) {
    var data = '';
    req.on('data', function(chunk) {
      data += chunk;
    }
    req.on('end', function() {
      m[handler].run(req, data, function(response) {
        response.headers = help.joinObjects(config.responseHeaders, response.headers);
        res.writeHead(response.code, response.headers);
        res.end(response.data);
      });
    }
  }

}

“处理程序”模块/函数运行回调函数并将响应(代码、标头和数据)传递给它。然后回调函数将标头与配置文件中设置的一组默认标头合并。

问题:当有两个连接同时调用help.joinObjects()(这是我的猜测)时,response.headers 属性与另一个用户/连接中的一个发生冲突并返回错误数据。如果我注释掉进行合并的行,则不会发生这种情况。

问题:我的“帮助”模块有什么问题?这里有一些我不明白的范围问题。

【问题讨论】:

  • 可能是因为您将响应中的标头合并到配置中?将help.joinObjects(config.responseHeaders, response.headers); 更改为help.joinObjects(response.headers, config.responseHeaders); 是否可以解决您的问题?
  • 嘿!不,这不是问题。最后的headers 属性包含应该发送回一个完全不同的客户端的标头(可怕!)。它们不是来自配置文件。问题在于,一些本应是客户端唯一的数据实际上是由碰巧同时发送请求的两个(或多个)客户端共享的。我认为所有的东西都封装得很好,不会在不同的连接之间共享,但事实证明它不是?..
  • 但是js是单线程运行的,所以没有竞态条件。你确定我的建议没有帮助吗? (抱歉再次问:))
  • 我无法通过您的修复重现该问题,而我的版本仍然存在该问题。因此,您的建议可能已经解决或隐藏了问题,但问题是 - 如何?.. 在某些时候,两个不同的用户连接必须访问相同的范围,因为 config.responseHeadersresponse.headers 都不包含我可以检测到的标头返回时在我的浏览器中。并且该特定标头是从我当时未访问的单独模块返回的。所以我很确定代码中存在范围问题。
  • 好的,知道了! config 在全局(或顶部,无关紧要)中,并且由于 JavaScript 通过引用传递变量,因此我的 joinObjects 函数在每次调用时都会修改全局对象的属性(即 - config 属性)。我的坏:(

标签: javascript node.js scope


【解决方案1】:

正如 lazyhammer 所指出的,问题在于我将对象传递给辅助函数的顺序:help.joinObjects(config.responseHeaders, response.headers)

Javascript 通过引用传递变量,因此每次调用help.joinObjects() 时,它都会覆盖配置属性而不是用户特定的对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 2023-03-25
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多