簡體   English   中英

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

[英]What is the better practice for sharing variables across Node.js modules

因此,我正在使用 Socket.io 編寫多人游戲,並且大部分套接字調用都在主文件 (app.js) 中處理,包括存儲用戶名和它們所連接的套接字。

但我想創建一個單獨的文件 (game.js) 來處理所有游戲代碼,包括特定房間的套接字排放。 但是,要做到這一點,我需要使用存儲在其中的用戶/套接字(在 app.js 中)訪問我的數組

所以我想知道共享變量的最佳方式是什么? 我應該通過我需要它的每個函數傳遞數組引用嗎? 或者我應該編寫一個調用一次的函數並創建一個全局變量(或我需要它的范圍)並引用數組?

另外,如果我需要在多個文件之間共享相同的依賴項,我應該在每個文件中調用 require 嗎?

關於模塊和使用全局/共享狀態

模塊的一個有趣方面是它們的評估方式。 該模塊在第一次需要時被評估,然后被緩存。 這意味着無論我們需要多少次,在對它進行評估之后,我們總是會得到相同的導出對象。

這意味着,雖然 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);

因此,對於您的特定問題,您想要共享的共享狀態可以駐留在由您擁有的任何模塊公開的單例對象中。 只要確保您的單例對象是在您的模塊中公開的對象,並且每次您需要它時,您總是會得到對它的引用。

如果“變量”是指對套接字的引用 - 您可能需要考慮將回調或模塊傳遞給處理發射的 game.js - 但該 game.js 在必要時調用。

就像 Edwin Dalorzo 提到的那樣,為所有變量創建一個單獨的文件似乎是最好的。

幾個小時以來,我遇到了類似的問題,因為我不知道變量是持久的。 我的場景是:

我有兩個文件cli.tsmain-lib.ts cli.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 };

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM