2016-07-01 1 views
2

module.exports = <ClassName>을 수행 할 때 순환 종속성에 문제가 있습니다.클래스가있는 NodeJS 4의 순환 종속성 처리

다음은 예입니다. ClassC에는 ClassB가 필요하고 ClassB에는 ClassA가 필요하고 ClassA에는 ClassC이 필요합니다. 내가 ClassC는 명백한 오류가 얻을 노드 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(); 

: 그리고 main.js에서 우리가 ClassC의 새로운 인스턴스를 생성하고 메소드를 호출, 그 통화의 사슬을 할 것입니다 해결되지 않았습니다. ClassC이를 ClassA에서 요구 한 때, 여전히 빈 객체가 반환 된 이후 classC.js의 말에 module.exports가 그 동안 ClassC로 덮어 쓸 ClassC로드의 과정 이었기 때문에

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) 

발생 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

이동을 시도하면 클래스 정의로 파일 끝으로 호출해야합니다. 이 작업 예 :

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

참고 최대 호출 스택 오류가 발생합니다 c.foo() 전화. 그러나 모든 클래스 참조는 예상대로 해결됩니다.

+0

예, 작동합니다. 감사합니다! 그러나 사소한 단점은 필자가 모든 파일을 파일 끝에 넣을 수는 없다는 것입니다. 상속을 위해 클래스 선언 전에 기본 클래스를 요구해야합니다.일부 파일은 파일 상단에, 일부 파일은 끝에있는 것처럼 보입니다. 이것 이외에 이것은 좋아 보인다. – Aides

+0

@Aides : 어쨌든 순환 상속을 가질 수 없습니다. 부모는 하위 클래스를 가져 오지 않아야합니다. – Bergi

+0

@Aides yep 분리 된 의존성 블록이있는 작은주의 사항이 있습니다. 그러나 이것은 정의 시간에 node.js의 순환 종속성을 해결할 수있는 유일한 방법입니다. –