- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在 Node 中,我看到模块内部全局初始化的变量在请求之间混淆了[一个请求所做的更改会影响另一个请求]。例如:
a.js
var a;
function printName(req, res) {
//get param `name` from url;
a = name;
res.end('Hi '+a);
}
module.exports.printName = printName;
index.js
//Assume all createServer stuffs are done and following function as a CB to createServer
function requestListener(req, res) {
var a = require('a');
a.printName(req, res);
}
根据我的假设,每次新请求到达 Node 时都会执行从模块“a”导出的 printName 函数,并且每次都会有不同的范围对象。
因此,在模块中拥有一些全局的东西不会跨请求影响它们。
但我发现情况并非如此。谁能解释 Node 如何以特定的方式处理函数的模块导出[它处理缓存模块导出对象范围的方式],以及如何克服模块内跨请求共享的全局变量?
编辑[我们根据请求执行异步任务]:在我们的实时系统中有快速请求。基本上查询 redis 并响应请求。我们看到错误的响应映射到错误的请求(redis 查找的回复 [存储在模块中的全局变量中] 错误地映射到 diff req)。而且我们还有一些默认值作为全局变量,可以根据请求参数覆盖它们。这也搞砸了
最佳答案
了解正在发生的事情的第一步是了解幕后发生的事情。从语言的角度来看, Node 模块没有什么特别之处。 “魔法”来自 Node 如何在您require
时从磁盘加载文件。
当您调用require
时, Node 会从磁盘同步读取或返回模块的缓存导出对象。读取文件时,遵循a set of somewhat complex rules要准确确定哪个文件被读取,但是一旦它有一个路径:
require.cache[moduleName]
是否存在。如果是,返回并停止。code = fs.readFileSync(path)
。code
与字符串 (function (exports, require, module, __filename, __dirname) {
... });
<eval
您的包装代码并调用匿名包装函数。
var module = { exports: {} };
eval(code)(module.exports, require, module, path, pathMinusFilename);
将 module.exports
保存为 require.cache[moduleName]
。
下次您需要
同一个模块时, Node 只返回缓存的exports
对象。 (这是一件非常好的事情,因为初始加载过程是缓慢且同步的。)
所以现在你应该能够看到:
global
或不使用 var
限定变量的范围)在您的示例中,您需要
每个请求的模块a,但您实际上在所有请求之间共享相同的模块范围,因为上面概述的模块缓存机制。对 printName
的每次调用在其范围链中共享相同的 a
(即使 printName
本身在每次调用时都会获得一个新的范围)。
现在在您的问题中的文字代码中,这并不重要:您设置 a
然后在下一行使用它。控制永远不会离开 printName
,因此共享 a
的事实是无关紧要的。我猜你的真实代码看起来更像:
var a;
function printName(req, res) {
//get param `name` from url;
a = name;
getSomethingFromRedis(function(result) {
res.end('Hi '+a);
});
}
module.exports.printName = printName;
这里我们遇到了一个问题,因为控件确实离开了printName
。回调最终会触发,但同时另一个请求更改了 a
。
你可能想要更像这样的东西:
a.js
module.exports = function A() {
var a;
function printName(req, res) {
//get param `name` from url;
a = name;
res.end('Hi '+a);
}
return {
printName: printName
};
}
index.js
var A = require('a');
function requestListener(req, res) {
var a = A();
a.printName(req, res);
}
这样,您就可以在 A
中为每个请求获得一个全新且独立的范围。
关于node.js - 模块中的 Node js 全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16396250/
我正在学习构建单页应用程序 (SPA) 所需的所有技术。总而言之,我想将我的应用程序实现为单独的层,其中前端仅使用 API Web 服务(json 通过 socket.io)与后端通信。前端基本上是
当我看到存储在我的数据库中的日期时。 这是 正常 。日期和时间就是这样。 但是当我运行 get 请求来获取数据时。 此格式与存储在数据库 中的格式不同。为什么会发生这种情况? 最佳答案 我认为您可以将
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在尝试使用backbone.js 实现一些代码 和 hogan.js (http://twitter.github.com/hogan.js/) Hogan.js was developed ag
我正在使用 Backbone.js、Node.js 和 Express.js 制作一个 Web 应用程序,并且想要添加用户功能(登录、注销、配置文件、显示内容与该用户相关)。我打算使用 Passpor
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我尝试在 NodeJS 中加载数据,然后将其传递给 ExpressJS 以在浏览器中呈现 d3 图表。 我知道我可以通过这种方式加载数据 - https://github.com/mbostock/q
在 node.js 中,我似乎遇到了相同的 3 个文件名来描述应用程序的主要入口点: 使用 express-generator 包时,会创建一个 app.js 文件作为生成应用的主要入口点。 通过 n
最近,我有机会观看了 john papa 关于构建单页应用程序的精彩类(class)。我会喜欢的。它涉及服务器端和客户端应用程序的方方面面。 我更喜欢客户端。在他的实现过程中,papa先生在客户端有类
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是一个图形新手,需要帮助了解各种 javascript 2D 库的功能。 . . 我从 Pixi.js 中得到了什么,而我没有从 Konva 等基于 Canvas 的库中得到什么? 我从 Konva
我正在尝试将一些 LESS 代码(通过 ember-cli-less)构建到 CSS 文件中。 1) https://almsaeedstudio.com/ AdminLTE LESS 文件2) Bo
尝试查看 Express Passport 中所有登录用户的所有 session ,并希望能够查看当前登录的用户。最好和最快的方法是什么? 我在想也许我可以在登录时执行此操作并将用户模型数据库“在线”
我有一个 React 应用程序,但我需要在组件加载完成后运行一些客户端 js。一旦渲染函数完成并加载,运行与 DOM 交互的 js 的最佳方式是什么,例如 $('div').mixItUp() 。对
请告诉我如何使用bodyparser.raw()将文件上传到express.js服务器 客户端 // ... onFilePicked(file) { const url = 'upload/a
我正在尝试从 Grunt 迁移到 Gulp。这个项目在 Grunt 下运行得很好,所以我一定是在 Gulp 中做错了什么。 除脚本外,所有其他任务均有效。我现在厌倦了添加和注释部分。 我不断收到与意外
我正在尝试更改我的网站名称。找不到可以设置标题或应用程序名称的位置。 最佳答案 您可以在 config/ 目录中创建任何文件,例如 config/app.js 包含如下内容: module.expor
经过多年的服务器端 PHP/MySQL 开发,我正在尝试探索用于构建现代 Web 应用程序的新技术。 我正在尝试对所有 JavaScript 内容进行排序,如果我理解得很好,一个有效的解决方案可以是服
我是 Nodejs 的新手。我在 route 目录中有一个 app.js 和一个 index.js。我有一个 app.use(multer....)。我还定义了 app.post('filter-re
我正在使用 angular-seed用于构建我的应用程序的模板。最初,我将所有 JavaScript 代码放入一个文件 main.js。该文件包含我的模块声明、 Controller 、指令、过滤器和
我是一名优秀的程序员,十分优秀!