Sharing & modifying a variable between multiple files node.js

我的未来我决定 提交于 2019-11-26 19:17:53

问题


main.js

var count = 1;

// psuedocode
// if (words typed begins with @add)
require('./add.js');

// if (words typed begins with @remove)
require('./remove.js');

// if (words typed begins with @total)
require('./total.js');



module.exports.count = count;

total.js

var count = require('./main.js').count;
console.log(count);

add.js

var count = require('./main.js').count;
count += 10;
console.log(count);

remove.js

var count = require('./main.js').count;
count -= 10;
console.log(count);

console.log

 1
 11
 -9

Background:

I have an application (irc bot), and I want to add a feature that peeps can do @add 1 or @remove 1. I have a main.js that then requires different files depending on the triggers that are said. So add would trigger the add.js file, and that would then require('main.js') and add 10 (10 for simplification, it'll actually parse the number and use that number) to it. The problem I'm having is when someone goes about and does @remove. It require('main.js') and subtracts 10 from 1 resulting in -9. And doing @total would output 1.

I've done a fairly good search for module.exports and I haven't come across an example like the one i listed above. The docs don't include any examples close to what I'm wanting to do; and these questions 1, 2 I understand--but aren't of any usefulness to me--as I understand what's being said there.

Question:

I'd like to have both @add and @remove manipulate the same variable ( count ), and for @total to return the total of count with the @add and @removes taken into account. Am I using module.exports incorrectly; or is there a common way that variables are shared, with one file being able to modify the contents of the module.exports and returning the results to the main.js file?


回答1:


Your problem is that when you do var count = require('./main.js').count;, you get a copy of that number, not a reference. Changing count does not change the "source".

However, you should have the files export functions. Requiring a file will only run it the first time, but after that it's cached and does not re-run. see docs

Suggestion #1:

// main.js
var count = 1;
var add = require('./add.js');
count = add(count);

// add.js
module.exports = function add(count) {
    return count+10;
}

#2:

var count = 1;
var add = function() {
    count += 10;
}
add();

#3: Personally i would create a counter module (this is a single instance, but you can easily make it a "class"):

// main.js
var counter = require('./counter.js');
counter.add();
console.log(counter.count);

// counter.js
var Counter = module.exports = {
    count: 1,
    add: function() {
        Counter.count += 10;
    },
    remove: function() {
        Counter.count += 10;
    }
}



回答2:


Not sure if this new or not but you can indeed share variables between files as such:

main.js

exports.main = {
    facebook: null
};

counter.js

var jamie = require('./main'); 
console.info(jamie); //{facebook: null}
jamie.main.facebook = false;
console.info(jamie); //{facebook: false}

anothercheck.js

var jamie = require('./main'); 
console.info(jamie); //{facebook: null} //values aren't updated when importing from the same file.
jamie.main.facebook = true;
console.info(jamie); //{facebook: true}

Now you can share between files.




回答3:


I have same problem like you,.. Sometimes I'd like to sharing variables between multiple files because I love modular style eg. separating controller, function, models in different folders/files on my node.js script so I can easy manage the code.

I don't know if this is the best solution but I hope will suit your needs.

models/data.js

// exports empty array
module.exports = [];

controllers/somecontroller.js

var myVar = require('../models/data');
myVar.push({name: 'Alex', age: 20});
console.log(myVar);
//  [{ name: 'Alex', age: 20 }]

controllers/anotherController.js

var myVar = require('../models/data');

console.log(myVar);
// This array has value set from somecontroller.js before...
//  [{ name: 'Alex', age: 20 }]

// Put new value to array
myVar.push({name: 'John', age: 17});
console.log(myVar);
// Value will be added to an array
//  [{ name: 'Alex', age: 20 }, { name: 'John', age: 17}]



回答4:


There is no way you can share a reference between different files. You shouldn't be.

I have a main.js that then requires different files depending on the triggers that are said

I don't think that's a good idea. All require statements you'll ever need must be at the top of the file.

I also see that You're requiring main.js in total.js and total.js in main.js. The require() function imports the module.exports of the file and assigns it to the namespace you provide. Your code shouldn't be split into files this way. You extract code into separate files only when they're modules by themselves. And if you do, you wouldn't be importing 2 files on each other.

It is also good to note that in javascript, when you assign something to a namespace, It gets copied (cloned) if it's a primitive. If it's an object, both namespaces then refer to the same object

var num = 5; 
var prim = num;
prim++; // prim is 6, but num is still 5.

var num = {five:5};
var ob  = num;
ob.five = 6;
console.log(num.five) //also 6.



回答5:


A little hack that works but isn't recommended is using the process variable. You can apply different properties to it and essentially use them like you would the window object in browser-based JS. This little hack will provide a reference to the variable. It can be changed and manipulated and the change will carry over to all files that are required.

But do note that it is not recommended as overriding the process variable could have some unexpected effects and is subject to loss of information should another process interfere.


file1.js:

const s1 = require('./file2');
process.num = 2;
console.log("file1", process.num);
s1.changeNum();
console.log("file1", process.num);

file2.js:

module.exports.changeNum = () => {
    process.num = 3;
    console.log("file2", process.num);
};

output:

file1 2

file2 3

file1 3




回答6:


alternatively, to all other answers

getters & setters

var _variableThing = 1223

module.exports = {
  get variableThing(){
    return _variableThing
  },

  set variableThing(val){
    _variableThing = val
  }
}

won't work with direct imports though



来源:https://stackoverflow.com/questions/17120117/sharing-modifying-a-variable-between-multiple-files-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!