Подтвердить что ты не робот

Совместное использование и изменение переменной между несколькими файлами 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?

4b9b3361

Ответ 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
  }
}

не будет работать с прямым импортом, хотя