node.js - Node js globals within modules -


in node see variables initialized global inside modules getting mixed [changes done 1 request affects other] across requests. ex:

a.js

var a; function printname(req, res) {   //get param `name` url;   = name;   res.end('hi '+a); } module.exports.printname = printname; 

index.js

//assume createserver stuffs done , following function cb createserver function requestlistener(req, res) {   var = require('a');   a.printname(req, res); } 

as per assumption, printname function exported module 'a' executed everytime new request hits node , have different scope object everytime.

so, having global inside module wouldn't affecting them across requests.

but see isn't case. can explain how node handle module exports of functions in specific [way handles scope of cached module exports object] , how overcome shared global variables across requests within module?

edit [we async task per request]: rapid requests in our live system. query redis , responds request. see wrong response mapped wrong request (reply [stored in global var in module] of redis wrongly mapped diff req). , have default values global vars can overridden based on request params. getting screwed up

the first step understanding happening understanding what's happening behind scenes. language standpoint, there's nothing special node modules. 'magic' comes how node loads files disk when require.

when call require, node either synchronously reads disk or returns module's cached exports object. when reading files, follows a set of complex rules determine which file read, once has path:

  1. check if require.cache[modulename] exists. if does, return , stop.
  2. code = fs.readfilesync(path).
  3. wrap (concatenate) code string (function (exports, require, module, __filename, __dirname) { ... });
  4. eval wrapped code , invoke anonymous wrapper function.

    var module = { exports: {} }; eval(code)(module.exports, require, module, path, pathminusfilename); 
  5. save module.exports require.cache[modulename].

the next time require same module, node returns cached exports object. (this thing, because initial loading process slow , synchronous.)

so should able see:

  • top-level code in module executed once.
  • since executed in anonymous function:
    • 'global' variables aren't global (unless explicitly assign global or don't scope variables var)
    • this how module gets local scope.

in example, require module a each request, but you're sharing same module scope across requrests because of module caching mechanism outlined above. every call printname shares same a in scope chain (even though printname gets new scope on each invocation).

now in literal code have in question, doesn't matter: set a , use on next line. control never leaves printname, fact a shared irrelevant. guess real code looks more like:

var a; function printname(req, res) {   //get param `name` url;   = name;   getsomethingfromredis(function(result) {       res.end('hi '+a);   }); } module.exports.printname = printname; 

here have problem because control does leave printname. callback fires, request changed a in meantime.

you want more this:

a.js

module.exports = function a() {     var a;     function printname(req, res) {       //get param `name` url;       = name;       res.end('hi '+a);     }      return {         printname: printname     }; } 

index.js

var = require('a'); function requestlistener(req, res) {   var = a();   a.printname(req, res); } 

this way, fresh , independent scope inside of a each request.


Comments