Совместное использование и изменение переменной между несколькими файлами node.js
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
История:
У меня есть приложение (irc bot), и я хочу добавить функцию, которую peeps может сделать @add 1 или @remove 1. У меня есть main.js, который затем требует разных файлов в зависимости от триггеров, которые указаны. Таким образом, add будет запускать файл add.js, а затем потребуется ( "main.js" ) и добавить 10 (10 для упрощения, он фактически проанализирует номер и использовать этот номер). Проблема, с которой я сталкиваюсь, - это когда кто-то идет и делает @remove. Он требует ( "main.js" ) и вычитает 10 из 1, что приводит к -9. И выполнение @total будет выводить 1.
Я сделал довольно хороший поиск для modules.exports, и я не сталкивался с примером, подобным приведенному выше. Документы не содержат каких-либо примеров, близких к тому, что я хочу делать; и эти вопросы 1, 2 Я понимаю - но не полезен для меня - как я понимаю, что там сказано.
Вопрос:
Я бы хотел, чтобы и @add, и @remove управляли одной и той же переменной (count), а для @total возвращали общее количество с учетом @add и @removes. Я неправильно использую module.exports; или существует общий способ обмена переменными, причем один файл может изменять содержимое модуля .exports и возвращать результаты в файл main.js?
Ответы
Ответ 1
Ваша проблема в том, что когда вы делаете var count = require('./main.js').count;
, вы получаете копию этого номера, а не ссылку. Изменение count
не изменяет "источник".
Однако у вас должны быть функции экспорта файлов. Требование файла будет запускаться только в первый раз, но после этого оно кэшируется и не запускается повторно. посмотреть документы
Предложение № 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: Лично я бы создал счетчик-модуль (это единственный экземпляр, но вы можете легко сделать его "классом" ):
// 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
Не уверен, что это новое или нет, но вы действительно можете делить переменные между файлами как таковые:
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}
Теперь вы можете делиться между файлами.
Ответ 3
У меня такая же проблема, как и вы,.. Иногда мне хотелось бы использовать переменные между несколькими файлами, потому что я люблю модульный стиль, например. разделяя контроллер, функцию, модели в разных папках/файлах на моем node.js script, поэтому я могу легко управлять кодом.
Я не знаю, является ли это лучшим решением, но я надеюсь, что это подойдет вашим потребностям.
модели /data.js
// exports empty array
module.exports = [];
Контроллеры /somecontroller.js
var myVar = require('../models/data');
myVar.push({name: 'Alex', age: 20});
console.log(myVar);
// [{ name: 'Alex', age: 20 }]
Контроллеры /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
Нельзя использовать ссылку между разными файлами. Вы не должны быть.
У меня есть main.js, который затем требует разных файлов в зависимости от триггеров, которые были упомянуты
Я не думаю, что это хорошая идея. Все запросы, которые вам понадобятся, должны находиться в верхней части файла.
Я также вижу, что вам требуется main.js
в total.js
и total.js
в main.js
. Функция require()
импортирует module.exports
файла и назначает его пространству имен, которое вы предоставляете. Таким образом, ваш код не должен разбиваться на файлы. Вы извлекаете код в отдельные файлы только тогда, когда они сами являются модулями. И если вы это сделаете, вы не будете импортировать 2 файла друг на друга.
Также хорошо заметить, что в javascript, когда вы присваиваете что-то пространству имен, он копируется (клонируется), если это примитив. Если это объект, то оба пространства имен ссылаются на один и тот же объект
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
Небольшой хак, который работает, но не рекомендуется, использует переменную process
. Вы можете применять к нему различные свойства и, по существу, использовать их так же, как объект window
в JS на основе браузера. Этот маленький хак даст ссылку на переменную. Это может быть изменено и изменено, и изменение будет перенесено на все файлы, которые require
d.
Но обратите внимание, что это не рекомендуется, поскольку переопределение переменной process
может иметь некоторые неожиданные последствия и может привести к потере информации в случае вмешательства другого процесса.
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);
};
вывод:
file1 2
file2 3
file1 3
Ответ 6
в качестве альтернативы, ко всем остальным ответам
добытчики и сеттеры
var _variableThing = 1223
module.exports = {
get variableThing(){
return _variableThing
},
set variableThing(val){
_variableThing = val
}
}
не будет работать с прямым импортом, хотя