首页 > 解决方案 > NodeJS上的全局变量赋值是原子的吗?

问题描述

我正在 Node 上开发一个有状态的 websocket 服务器。我们需要一条对业务逻辑很重要的只读数据,并将其保存在 Node 的全局范围内,最近我们必须使此 require 缓存无效并重新请求以允许在运行时更改该数据。我的问题是我们是否应该担心简单地重新分配全局变量重新要求的结果会导致并发连接之间出现问题,这些连接在不同阶段读取这个数据的单个副本?谢谢!

标签: javascriptwebsocketconcurrencyglobal-variablesnodejs-server

解决方案


NodeJS上的全局变量赋值是原子的吗?

因为 node.js 仅将 Javascript 作为单线程运行,所以所有分配在 Javascript 中都是原子的。

我们是否应该担心简单地将重新分配的结果重新分配给全局变量会导致在不同阶段读取这个单一数据副本的并发连接之间出现问题?

您不必担心分配不是原子的。

如果一行代码在重新赋值给全局var之前读取了这个全局变量并将其值赋值给另一个局部变量,那么这个局部变量的值会在重新赋值之后自动刷新吗?

先前有权访问数据的模块是否会在分配后看到新数据取决于代码的精确细节和变量中的内容。要具体评论您的情况,您必须向我们展示实际代码以及操作中分配的变量中的内容。

这是 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

推荐阅读