2016-07-01 6 views
2

Ich habe ein Problem mit zirkulären Abhängigkeiten, wenn module.exports = <ClassName>.Umgang mit zirkulären Abhängigkeiten in NodeJS 4 mit Klassen

Hier ist ein Beispiel. ClassC erfordert ClassB, ClassB erfordert ClassA, ClassA erfordert ClassC. Und in main.js wir eine neue Instanz von ClassC nur erstellen und rufen Sie die Methode, dass eine Kette von Aufrufen tun:

/* classA.js */ 
'use strict'; 

const ClassC = require('./classC.js'); 
class ClassA { 
    foo() { 
     console.log('ClassA.foo'); 
     var classC = new ClassC(); 
     classC.bar(); 
    } 
} 

module.exports = ClassA; 

/* classB.js */ 
'use strict'; 

const ClassA = require('./classA.js'); 
class ClassB { 
    foo() { 
     console.log('ClassB.foo'); 
     var classA = new ClassA(); 
     classA.foo(); 
    } 
} 

module.exports = ClassB; 

/* classC.js */ 
'use strict'; 

const ClassB = require('./classB.js'); 
class ClassC { 
    foo() { 
     console.log('ClassC.foo'); 
     var classB = new ClassB(); 
     classB.foo(); 
    } 

    bar() { 
     console.log('ClassC.bar'); 
    } 
} 

module.exports = ClassC; 

/* main.js */ 
'use strict'; 

const ClassC = require('./classC.js'); 

var classC = new ClassC(); 
classC.foo(); 

Also, wenn ich rufe tun Knoten main.js Ich bekomme ein offensichtlicher Fehler, dass ClassC ist Nicht gelöst.

D:\Projects\test-circular-reference-es6\classA.js:8 
     var classC = new ClassC(); 
        ^
TypeError: ClassC is not a function 
    at ClassA.foo (D:\Projects\test-circular-reference-es6\classA.js:8:22) 
    at ClassB.foo (D:\Projects\test-circular-reference-es6\classB.js:9:16) 
    at ClassC.foo (D:\Projects\test-circular-reference-es6\classC.js:9:16) 
    at Object.<anonymous> (D:\Projects\test-circular-reference-es6\main.js:7:8) 
    at Module._compile (module.js:409:26) 
    at Object.Module._extensions..js (module.js:416:10) 
    at Module.load (module.js:343:32) 
    at Function.Module._load (module.js:300:12) 
    at Function.Module.runMain (module.js:441:10) 
    at startup (node.js:139:18) 

Dies geschieht, weil, wenn ClassC in KlasseA erforderlich war es immer noch ein Prozess der ClassC Beladung war, also ein leeres Objekt und später am Ende des classC.js der module.exports wurde, während das mit ClassC überschrieben wurde zurückgegeben Verweis auf leeres Objekt in classA.js blieb so wie es war.

Die Frage ist also, wie man damit umgehen soll, was ist die beste Methode, um sowohl zirkuläre Referenzen als auch exportierende Klassen in NodeJS 4.x (ES6) zu haben?

Von meiner Seite sehe ich die folgenden Möglichkeiten:

  1. nicht module.exports überschreiben und wie module.exports.class = ClassC; etwas tun und dann instanziiert wie new ClassC.class(); Aber dies führt auch mehr Schwierigkeiten für die Vererbung und plump Code im Allgemeinen.
  2. Verwenden Sie stattdessen TypeScript, weil es dieses Zeug behandelt.

Alle Vorschläge sind willkommen.

+1

* Verwenden Sie stattdessen TypeScript, weil es mit diesem Zeug umgehen wird. * Wirklich? – nils

+1

@ Nils und ändern Sie die Sprache jedes Mal, wenn Sie neue Probleme begegnen! –

+0

Ich denke, es gibt eine Variante # 3 mit 'require' von ClassB im Konstruktor des ClassC. Zum Zeitpunkt des Aufrufs des Konstruktors befindet sich das Objekt mit ClassB bereits im Cache und ist damit einsatzbereit. Das Problem ist der Code wird wirklich chaotisch. – dazewell

Antwort

1

Versuchen Sie, Anruf mit der Klassendefinition in das Ende der Datei zu verschieben. Dies funktioniert Beispiel:

// a.js 
class A { 
    foo() { 
     var c = new C(); 
     c.foo(); 
    } 
} 

module.exports = A; 
const C = require('./c.js'); 

// b.js 
class B { 
    foo() { 
     var c = new C(); 
     c.foo(); 
    } 
} 

module.exports = B; 
const C = require('./c.js'); 

// c.js 
class C { 
    foo() { 
     var a = new A(); 
     a.foo(); 
    } 
} 

module.exports = C; 
const A = require('./a.js'); 

// main.js 
const C = require('./c.js'); 
const B = require('./b.js'); 

const c = new C(); 
const b = new B(); 

c.foo(); 
b.foo(); 

HINWEIS Das c.foo() nennen max Call-Stack Fehler verursachen. Aber alle Klassenreferenzen werden wie erwartet gelöst.

+0

Ja, es wird funktionieren, danke! Aber ein kleiner Nachteil ist, dass ich nicht alle Anforderungen am Ende der Datei, z. Für die Vererbung muss ich vor der Klassendeklaration eine beliebige Basisklasse verlangen.Es sieht so aus, als ob einige Anforderungen am Anfang der Datei und einige am Ende stehen. Ansonsten sieht das gut aus. – Aides

+0

@Aides: Sie können sowieso keine zirkuläre Vererbung haben. Das übergeordnete Element sollte seine Unterklassen nicht importieren. – Bergi

+0

@Aids yep gibt es eine kleine Einschränkung mit getrennten Abhängigkeitsblock. Dies ist jedoch der einzige Weg, zirkuläre Abhängigkeiten in node.js zur Definitionszeit aufzulösen. –

Verwandte Themen