Является ли глобальное присвоение переменной атомарным на NodeJS? - PullRequest
0 голосов
/ 03 ноября 2018

Я работаю на сервере с отслеживанием состояния и веб-сокетом в Node. Нам требуется фрагмент данных только для чтения, который важен для логики бизнеса, и мы сохраняем его в глобальной области видимости Node, и недавно нам пришлось аннулировать это требование кэш-памяти и повторно требовать изменения этого фрагмента данных во время выполнения. Мой вопрос заключается в том, стоит ли нам беспокоиться, просто переназначая глобальную переменную; результат повторного требования вызовет проблемы между параллельными соединениями, которые читают эту единственную копию данных на разных этапах? Спасибо!

1 Ответ

0 голосов
/ 03 ноября 2018

Является ли глобальное присвоение переменной атомарным на NodeJS?

Поскольку node.js запускает ваш Javascript только как однопоточный, все назначения в Javascript являются атомарными.

Стоит ли нам беспокоиться, если просто переназначить глобальную переменную, результат повторного запроса вызовет проблемы между одновременными соединениями, которые читают эту единственную копию данных на разных этапах?

Вам не нужно беспокоиться о том, что задание не является атомарным.

Если строка кода считывает эту глобальную переменную и присваивает ее значение другой локальной переменной до переназначения глобальной переменной, будет ли значение этой локальной переменной автоматически обновляться после переназначения?

Будет ли модуль, который ранее имел доступ к данным, видеть новые данные после назначения или нет, зависит от точных деталей кода и того, что находится в переменных. Чтобы прокомментировать конкретную ситуацию, вам нужно показать нам реальный код и то, что находится в переменных, которые назначены в операции.

Вот общее описание назначения в Javascript. Назначение делает что-то другое в зависимости от того, что находится в переменной.

Примитивы копируются при назначении. Объекты присваиваются простым разделением указателя на объект (без копирования). Поэтому любой, у кого есть указатель на один и тот же объект, увидит все изменения свойств этого объекта, поскольку они указывают на один и тот же объект. Но если вы назначите новый объект главной переменной, тогда все остальные будут иметь указатель на предыдущий объект, а не новый объект.

Вот несколько примеров для иллюстрации:

let master = {name: "John"};

// x gets pointer to the same object that master points to
// both master and x point to the same object
let x = master;
console.log(x.name);    // "John"

// update property on master
// but, both variables point to the same object so both see
// the change in the property value on that object
master.name = "Alice";
console.log(master.name);  // "Alice"
console.log(x.name);       // "Alice"
console.log(x === master); // true, they both point to the same object

// reassign a new object to master variable
master = {name: "Drew"};

// x still points at original object that was originally in master
// and knows nothing about the whole new object in master now
console.log(master.name);  // "Drew" 
console.log(x.name);       // still "Alice", not "Drew"
console.log(x === master); // false, not the same object

Примитивные типы данных, такие как числа или логические значения, назначаются копией, поэтому после присвоения содержимого одной переменной другой связи между этими двумя переменными нет вообще. Каждый из них имеет свое собственное содержимое данных, поэтому изменение значения одной переменной не влияет на содержимое другой переменной.

 // primitive data value
 let master = 2;

 let x = master;
 console.log(x);     // 2

 master = 10;
 console.log(x);     // still 2
...