2016-07-01 6 views
2

module.exports = <ClassName>を実行すると循環依存性に問題があります。NodeJS 4の循環依存関係をクラスで処理する

ここは例です。 ClassCはClassBを要求し、ClassBはClassAを要求し、ClassAはClassCを要求する。そして、main.jsに私たちはクラスCの新しいインスタンスを作成し、呼び出しの連鎖を行いますメソッドを呼び出す:私はノードmain.jsを呼び出す行う際

/* 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(); 

は、だから私は、クラスCは明らかにエラーが発生します解決されません。

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) 

クラスCはA級に必要とされたとき、それは依然としてクラスCのローディングのプロセスであったので、空のオブジェクトが返されたそのながら後classC.jsの終わりにmodule.exportsはクラスCを用いて上書きされたので、これが起こりますclassA.jsの空のオブジェクトへの参照はそのまま残っていました。

これに対処する方法がありますが、NodeJS 4.x(ES6)の循環参照とエクスポートクラスの両方を持つベストプラクティスは何ですか?

  1. module.exportsはを上書きし、module.exports.class = ClassC;ような何かをしてからnew ClassC.class();のようにインスタンス化しかし、これはまた、一般的に継承し、不器用なコードのためのより多くの困難を紹介しません:私の側から

    は、私は以下の可能性のある方法を参照してください。

  2. 代わりにTypeScriptを使用します。これは、このような処理を行うためです。

ご提案は大歓迎です。

+1

*代わりにTypeScriptを使用してください。 – nils

+1

@nils新しい問題に会うたびに言語を変更してください! –

+0

私はClassCのコンストラクタの中にClassBの 'require'を実行する変種#3があると思います。コンストラクタ呼び出しの時点で、ClassBを持つオブジェクトはすでにキャッシュに入っているので、使用できる状態になります。 問題はコードが本当に乱雑になることです。 – dazewell

答えて

1

クラス定義でファイルの最後に移動する必要があります。 c.foo()は最大コールスタックエラーが発生します呼び出す

// 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(); 

:これは実施例です。しかし、すべてのクラス参照は、期待通りに解決されます。

+0

はい、うまくいくでしょう、ありがとう!しかし、マイナーな欠点は、ファイルの最後に必要なものをすべて入れることができないことです。継承のために、クラス宣言の前に基底クラスを必要とする必要があります。いくつかの要求はファイルの先頭にあり、最後にはいくつかのように見えます。それ以外はこれがよさそうだ。 – Aides

+0

@Aides:とにかく循環的な継承はできません。親はそのサブクラスをインポートすべきではありません。 – Bergi

+0

@Aides yep分離された依存関係ブロックで少し警告があります。しかしこれは、定義時にnode.jsの循環依存関係を解決する唯一の方法です。 –

関連する問題