全局变量替代方案

3
我想创建一个可供所有.js文件访问的数组。这个数组必须是可更新的,并且更新后的更改必须反映在使用该数组的所有其他文件中。 我已经了解到使用全局变量不是一个好方法,但是有什么替代方案吗?
//file 1 which contains my global variable
var mySharedArray = ['helo']; 
module.exports = {
mySharedArray: mySharedArray,
get: function(){
    console.log(mySharedArray);
} 
}    

//file 2 where i am pushing new-data 
router.get('/workerequestest',function(req,res){
queue.push("moreData");
require('../config/globalQueue').get();
require('../config/startWorkerQueue');
res.send(200,'message recieved');
});

//file 3 where i am checking the updated values
var interval = setInterval(function() {
var Queue = require('../config/globalQueue').mySharedArray;
require('../config/globalQueue').get();
}, 10000,'hello' ,'checking for New processes');

一个模块,在需要该变量的地方被调用。 - Kevin B
这与node.js没有任何关系。 - Blubberguy22
谢谢您的迅速回复。您能否再具体一些,最好能用一个例子来解释一下。 - Furious
2个回答

9

在Node.js中,正确的模块化不使用实际的全局变量,因为这会使得重用模块更加复杂,并可能与其他全局变量发生冲突。

可以使用的一种设计模式是将共享数据放在自己的模块中,然后在需要的地方使用require()引入该模块。

// shared-data.js
var mySharedArray = [...];

module.exports = {
    mySharedArray: mySharedArray
}

然后,在每个想要访问该数组的模块中,你可以这样做:
// someothermodule.js

var sharedArray = require('./shared-data.js').mySharedArray;


// this modification will change the main array and will be seen by
// all modules that are sharing it
sharedArray.push("moreData");

这是有效的,因为在Javascript中分配数组时,它们不会被复制,而是共享指向原始数组的指针。 因此,对分配的值进行任何修改只是指向原始对象,并且更改原始数组。 因此,所有模块都可以访问相同的原始数组。
我在我的三个文件中测试了这个概念,它运行良好。 这是我的三个文件:
服务器文件:
// shared-server.js
var express = require('express');
var app = express();
var server = app.listen(80);
var shared = require('./shared-var');
require('./shared-interval.js')

var cntr = 0;

app.use(express.static('public'));

app.get("/test", function(req, res) {
    shared.mySharedArray.push(++cntr);
    shared.get();
    res.send(200,'message received');
});

共享变量文件:

//shared-var.js
var mySharedArray = ['helo']; 
module.exports = {
    mySharedArray: mySharedArray,
    get: function(){
        console.log(mySharedArray);
    } 
}

时间间隔文件:

//shared-interval.js
var interval = setInterval(function() {
    require('./shared-var').get();
}, 1000);

当我运行此代码时,它每秒输出mySharedArray的值。每次使用浏览器访问http://localhost/test时,都会向mySharedArray添加一个新值,并在控制台中看到该值。这是我期望的行为。


谢谢您的回答@jfriend00。但是您能举个例子来解释一下吗? - Furious
我尝试使用上面的例子,但它没有起作用。我使用了三个文件:1. 用于存储数据;2. 用于更新数组;3. 用于获取更新后的数组。但是我无法在第三个文件中获取更新后的值。更新后的值只显示在第二个文件中。 - Furious
@Furious - 只要您修改数组对象而不是将新数组分配给它,它就可以正常工作。如果您想让我帮助您实现,请编辑您的问题并展示您尝试过的实际代码,这样我才能看到您的不同之处。 - jfriend00
var queue = require('../config/globalQueue').mySharedArray; 是存储全局变量的文件。 - Furious
@Furious - 你不能直接在多个进程之间共享变量。解决这种问题有多种可能的方法。一个进程可以持有队列,其他进程可以发送http请求来查询队列。或者,你可以使用像redis这样的内存存储来保存队列,并让每个进程通过redis访问队列。当在进程之间共享数据时,数据也必须被规范化为类似JSON的东西,因为你不能在进程之间传递实时的Javascript对象。 - jfriend00
显示剩余6条评论

1
你可以将它们放在一个单独的模块中,在你需要它的任何模块中引用它,否则你可以使用一个单独的存储服务,比如 redismemcached 来存储你的数据数组。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接