【问题标题】:What is the better practice for sharing variables across Node.js modules跨 Node.js 模块共享变量的更好做法是什么
【发布时间】:2021-09-13 21:35:09
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我应该在每个文件中调用 require -> 如果你很懒,你可以使用“npm fs”

标签: javascript node.js sockets


【解决方案1】:

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

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

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

//module config.js
 
dbConfig = {
  url:'mongodb://foo',
  user: 'anakin',
  password: '*******'
}
 
module. exports = dbConfig;

我们可以轻松地与任意数量的其他模块共享此模块,并且每个模块都将获得相同的配置对象实例,因为该模块只被评估一次,并且导出的对象被缓存在其上。

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

因此,对于您的具体问题,您想要共享的共享状态可以驻留在您拥有的任何模块公开的单例对象中。只需确保您的单例对象是在您的模块中公开的对象,并且每次您需要它时,您总会获得对它的引用。

【讨论】:

  • 谢谢,太好了!我想我真的不知道 require 是如何工作的
  • 会的!只是等待计时器结束
【解决方案2】:

如果“变量”是指对套接字的引用 - 您可能需要考虑将回调或模块传递给处理发射的 game.js - 但必要时会调用 game.js。

【讨论】:

    【解决方案3】:

    就像 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 };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 1970-01-01
      • 2016-05-26
      • 2021-11-04
      • 2023-03-05
      • 2020-05-03
      • 2016-07-07
      相关资源
      最近更新 更多