跨Node.js模块共享变量的更好做法是什么

时间:2014-07-19 00:16:09

标签: javascript node.js sockets

所以我用Socket.io编写了一个多人游戏,大多数套接字调用都在主文件(app.js)中处理,包括存储用户名和他们连接的套接字。

但是我想创建一个单独的文件(game.js)来处理所有游戏代码,包括某些房间的套接字排放。但是要做到这一点,我需要使用存储在其中的用户/套接字访问我的数组(在app.js中)

所以我想知道共享变量的最佳方式是什么?我应该通过我需要的每个函数传递数组引用吗? 或者我应该编写一个被调用一次的函数并创建一个全局变量(或我需要它的范围)并引用该数组?

另外如果我需要在多个文件中共享相同的依赖关系,我应该在每个文件中调用require吗?

3 个答案:

答案 0 :(得分:6)

关于模块和使用全局/共享状态

模块的一个有趣方面是它们的评估方式。在第一次需要时对模块进行评估,然后对其进行高速缓存。这意味着在评估它之后,无论我们需要它多少次,我们总会得到相同的导出对象。

这意味着,虽然Node提供了一个global对象,但最好使用模块来存储共享声明而不是直接将它放入全局对象中。例如,以下模块公开Mongo数据库的配置。

//module config.js

dbConfig = {
  url:'mongodb://foo',
  user: 'anakin',
  password: '*******'
}

module.exports = dbConfig;

我们可以轻松地与我们想要的其他模块共享此模块,并且每个模块都将获得配置对象的完全相同的实例,因为模块仅被评估一次,并且导出的对象从那里被缓存。 / p>

//foo.js
var dbConfig1 = require('./config');
var dbConfig2 = require('./config');
var assert = require('assert');
assert(dbConfig1==dbConfi2);

因此,对于您的特定问题,您要共享的共享状态可以驻留在由您拥有的任何模块公开的单个对象中。只需确保您的单例对象是模块中公开的对象,并且每次需要时都会得到一个引用它。

答案 1 :(得分:0)

如果用'variable'表示引用套接字 - 你可能要考虑将回调或模块传递给处理发射的game.js - 但是必要时会调用game.js。

答案 2 :(得分:0)

就像 Edwin Dalorzo 提到的那样,为所有变量创建一个单独的文件似乎是最好的。

几个小时以来我遇到了类似的问题,因为我不知道变量是持久的。我的场景是:

<块引用>

我有两个文件 cli.tsmain-lib.tscli.ts 读取用户输入,并根据输入运行 main-lib.ts 中的函数。当 main-lib.ts 忙于验证输入时,cli.ts 使用 main-lib.ts 在测试通过时生成的一些全局变量。唯一的限制是我不能将 main-lib.ts 代码与 cli.ts 混合使用,我只能共享函数 callValidateFunction

我最初想到的问题是:如果我要制作一个global-vars.ts文件,每次调用require(即调用setVar(...)),变量的数据仍然不同}} 只会改变导入的变量值。

但是,感谢 Edwin 的回答,我设法实现了一座桥:

// cli.ts

import { setVar, getVar } from "./var-bridge";
import { callValidateFunction } from "./main-lib";

function run(args: string[]): void {
    // ...
    if (arg == "--email") {
        // Set the test status.
        setVar("testStatus", "pending");
        
        // Validate the input email address.
        callValidateFunction("validateEmail", nextArg());
        
        // Get the testStatus.
        const testStatus: string = getVar("testStatus");
    }
    // ...
}
// main-lib.ts

import { setVar, getVar } from "./var-bridge";

const funcs: {name: string, func: (arg: string) => boolean} = {};

funcs.validateEmail = function(arg: string): boolean {
    let passed: boolean = false;
    // ...
    return passed;
};

function callValidateFunction(functionName: string, arg: string): void {
    // ...
    const passed = funcs[functionName](arg);
    if (passed) setVar("testStatus", "passed");
}

// ...
// var-bridge.ts

const variables: {name: string, value: any} = {
    "testStatus": "",
    // ...
};

function setVar(varName: string, varValue: any): void {
    variables[varName] = varValue;
}

function getVar(varName: string): any {
    return variables[varName];
}

export { setVar, getVar };