2016-04-23 9 views
1

das folgende Modul Gegeben:Knoten js - sind Module zwischen Benutzern geteilt?

module.exports = function() { 
    var env; 
    var module = {}; 

    module.setEnv= function(myEnv) { 
     env = myEnv; // env may be set to a different value per user 
    } 

    module.doActionWithEnv = function() { 
     ... 
    } 
    ... 

    return module; 
} 

Ich benötige das Modul wie folgt:

var myModule = require('/myModule')(); 

Jetzt ist meine Frage, ist mein Modul zwischen 2 verschiedenen Benutzern gemeinsam verwendet, die die Website besuchen? Damit meine ich, können Kollisionen auftreten, wenn ein Benutzer die private env Variable setzt, und dann ruft der andere eine Funktion innerhalb des Moduls auf, die von env abhängt und somit das falsche Ergebnis erhält?

Danke.

+0

Soweit ich weiß, wenn Sie nur eine Instanz Ihres Skripts haben, dann ja, die beiden Benutzer werden den gleichen Zustand teilen. – nils

+2

Wenn Sie nur ein 'myModule' erstellen, dann wird es von allen Benutzern geteilt. Das Exportieren einer "Funktion" erlaubt es Ihnen, mehrere Objekte zu erstellen, aber Sie müssen diese Funktion jedes Mal aufrufen, wenn Sie ein neues Objekt (pro Benutzer) wollen - 'var myModule = require ('/ myModule'); ... user.env = myModule(); ' –

+0

Wie kann ich dieses Problem dann vermeiden? –

Antwort

5

Variablen auf Ihrem Server sind im Allgemeinen einmal pro Serverprozess, nicht einmal pro Benutzer, der eine Anforderung stellt. Einige Variablen wie die Objekte req und res, die an einen Anforderungshandler übergeben werden, werden für jede Anforderung eindeutig erstellt. Pro Benutzervariablen wird normalerweise eine Art Sitzungsverwaltungsschicht benötigt, damit der Server erkennen kann, welcher Benutzer die Anforderung stellt und dann auf die für diesen bestimmten Benutzer gespeicherten Daten zugreift. Sie können lesen Express Sessions oder Node.js and Express Sessions oder Express.js Sessions – A Detailed Tutorial für weitere Informationen über die Verwendung von Sitzungen in Express und es gibt eine Reihe von NPM-Module für die Durchführung von Sitzungen mit Express, obwohl express-session ist wahrscheinlich die beliebteste.


Um über Ihren Code, in dieser Zeile des Codes zu erklären:

var myModule = require('/myModule')(); 

Sie erhalten ein neues myModule für jeden Anruf, dass bekommen. Jedes Mal, wenn Sie diesen Modulkonstruktor aufrufen, erhalten Sie ein neues myModule-Objekt mit einem neuen env darin.

Wenn Sie diesen Konstruktor nur einmal aufrufen und nur eine myModule Variable in Ihrem Code haben und mehrere Anfragen von Ihrem Webserver im Namen verschiedener Benutzer alle die gleiche myModule-Variable verwenden, dann teilen sie alle dasselbe myModule Objekt und damit das gleiche env Variable innerhalb davon.


Was verwirrend Ihre Situation etwas macht, ist, dass Module in node.js, die erstellt werden, wenn Sie require('/myModule') werden zwischengespeichert und geteilt in node.js. tun Es gibt also nur ein aktuelles myModule.js geladenes Modul, soweit das System node.js betroffen ist. Aber jedes Mal, wenn Sie den Modulkonstruktor aufrufen, erstellt Ihr eigener Code ein neues Objekt (das Sie auch module genannt haben, was die Dinge verwirrend macht). Also, wenn Sie, dass Konstruktor 5 mal nennen wie:

var m = require('/myModule'); 
var x1 = m(); 
var x2 = m(); 
var x3 = m(); 
var x4 = m(); 
var x5 = m(); 

Oder auch:

var x1 = require('/myModule')(); 
var x2 = require('/myModule')(); 
var x3 = require('/myModule')(); 
var x4 = require('/myModule')(); 
var x5 = require('/myModule')(); 

Dann haben Sie fünf separate Objekte in den Variablen x1 durch x5 und jeweils ihre eigenen haben env Variablen innerhalb.


Aber, wenn Sie ihn nur einmal tun:

var myObj = require('/myModule')(); 
myObj.setEnv("hello"); 

Und dann mehrere Request-Handler beziehen sich alle auf diesem myObj Objekt wie folgt:

app.get('/request1', function(req, res) { 
    myObj.setEnv("goodbye"); 
}}; 

app.get('/request2', function(req, res) { 
    myObj.setEnv("adios"); 
}}; 

Dann diese beiden Request-Handler werden auf dem gleichen myObj-Objekt betrieben, egal, welcher Benutzer die Anfrage initiiert.


Wie kann ich dieses Problem dann vermeiden?

Wenn Sie möchten, dass Benutzerinformationen auf Ihrem Server gespeichert werden, verwenden Sie normalerweise sessions. Obwohl es viele Möglichkeiten gibt, eine Sitzung zu implementieren, legen sie normalerweise beim ersten Besuch Ihrer Website ein eindeutiges Cookie für den Browser jedes Benutzers fest. Es gibt dann einen Speichermechanismus auf dem Server, der auf Daten zugreifen kann, die dem Benutzer mit diesem Cookie-Wert gehören. Sie verwenden keine normalen JS-Variablen zum Speichern des Status jedes Benutzers. Sie würden normalerweise entweder eine Objektsuche (nach Cookie-ID) oder eine Art Datenbank verwenden.

Da es so aussieht, als ob Sie Express verwenden, gibt es mehrere NPM-Module, die in Express eingebunden werden und Sitzungen für Sie implementieren. Die beliebteste Session-Implementierung für Express sind Express-Sitzungen.