2012-03-16 1 views
40

Ho intenzione di utilizzare il seguente modello per utilizzare il modulo basato su requireJS per agire come un singleton. Si noti che classA restituisce un'istanza di tipo 'classA', mentre il resto delle classi classB, classC e main restituiscono il tipo di classe dal modulo. Tutte queste sono classi basate sulla classe MooTools.È una cattiva pratica usare il modulo requireJS come un singleton?

L'idea è di utilizzare la classe A come un singleton disponibile a livello globale, i metodi sono solo riempitivi. Qualche idea se questo è un modello accettabile da usare?

Questo tornerà a mordermi in una fase successiva? Non ho ancora provato a eseguire r.js nel progetto, quindi sono un po 'preoccupato e cerco qualche consiglio.

// classA.js 
    define([], function() { 
     var classA = new Class({ 

      initialize: function (regionId) { 
       // perform some Initialization. 
       this.data = null; 
      }, 

      doSomething: function(param) { 
       // some thing. 
       this.data = param; 
      } 
     }; 

     return new classA(); 
    }); 

    // classB.js 
    define(["classA"], function(classA) { 
     var classB = new Class({ 

      initialize: function (regionId) { 
       // perform some Initialization. 
      }, 

      doSomethingElse: function() { 
       // some thing. 
       classA.doSomething("Go back to Work Now!"); 
      } 
     }; 

     return classB; 
    }); 


    // classC.js 
    define(["classA"], function(classA) { 
     var classB = new Class({ 

      initialize: function (regionId) { 
       // perform some Initialization. 
      }, 

      doSomethingElse: function() { 
       // some thing. 
       classA.doSomething("Time to Play!"); 
      } 
     }; 

     return classC; 
    }); 


    // main.js 
    define(["classA", "classB", "classC"], function(classA, classB, classC) { 
     var main = new Class({ 

      initialize: function (regionId) { 
       // perform some Initialization. 
       this.b = new classB(); 
       this.c = new classC(); 
      }, 

      doEverything: function() { 
       // some thing. 
       this.b.doSomethingElse(); 
       classA.doSomething("Nap Time!"); 
      } 
     }; 

     return main; 
    }); 

Grazie mille in anticipo ...

+1

Trovato un altro post che tocca lo stesso argomento - [collegamento] [http://stackoverflow.com/questions/7708194/dependency-injection-with-requirejs] – Karthik

risposta

37

No, non riesco a pensare a una ragione contro l'uso di single con require.js.

La definizione del modulo deve esportare il singleton. Il modo in cui lo fai va bene, dal momento che è un singleton potresti anche evitare lo new. Io uso qualcosa come

define(function (require) { 
    var singleton = function() { 
     return { 
      ... 
     }; 
    }; 
    return singleton(); 
}); 

Il primo require al modulo verrà caricato ed esportarlo. Alcuni altri moduli che richiedono il singleton riutilizzeranno solo quelli già esportati.

+2

Grazie per la risposta. Tuttavia, non sono chiaro su quale sia il vantaggio di evitare "nuovo"? Oppure, potrei dovrei chiedere, perché è meglio evitare "nuovo" nello scenario sopra? Il modulo viene caricato solo una volta in ogni caso, quindi * nuovo * viene eseguito solo una volta !? Potresti commentare? – Karthik

+4

Bene visto che è un singleton, un oggetto letterale è appropriato. Non c'è bisogno di costruttori, prototipi e tutto ciò di cui avresti bisogno se non si trattasse di un single ... – ggozad

+0

Ok, questo ha senso. Grazie! – Karthik

6

Questo tornerà a mordermi in una fase successiva?

Ho iniziato con il modello della risposta accettata qui, ma la mia sola pagina JavaScript app trasformato in un thread principale e un web worker perché stava facendo un sacco di calcoli e la pagina non è stato reattivo.

Come ho spostato alcuni dei moduli nel web worker, c'era un comportamento strano. Mi ci è voluto un sacco di tempo per capirlo, ma mi sono reso conto che alcuni dei miei moduli requirejs (in particolare i singleton) venivano caricati due volte.

Quello che ho scoperto è che se è richiesto un modulo Singleton nel thread principale e anche in modules that run in a web worker, il modulo singleton verrà caricato una seconda volta nel web worker (e quindi non è realmente un singleton). Una copia è nel thread principale, l'altra nel web worker. Se il tuo singleton memorizza le variabili, avrai due copie.

Tutto ha senso poiché il worker e il thread principale hanno spazi di indirizzi separati (forse questo è il motivo per cui ho ottenuto un downvote?). Sto postando la risposta qui perché qualcuno potrebbe incontrare lo stesso problema in quanto non vi è alcun avviso in requirejs.

La soluzione (nel mio caso) non era di mescolare i moduli tra il thread principale e il web worker. Questo può essere un grande vincolo progettuale che non è necessariamente un problema in ambienti come Java o C#.

+0

Grazie per aver postato questo follow-up. Posso vedere questo prendere un po 'di tempo per capire senza saperlo prima del tempo. – rorsach