簡體   English   中英

Node.js v.11.6.0:如何解決循環依賴性?

[英]Node.js v.11.6.0: How to resolve circular dependency?

在我的應用程序內部,我創建了許多ES6“類”,每個類都定義了它的屬性以及自定義設置器,在它們內部(分配屬性之前),它正在運行特定於字段的驗證器。 現在,由於模型可能具有相同的可用字段,並且我不想復制驗證器的代碼,因此我計划根據需要導入模型,並在通過類的靜態屬性公開驗證器時重新使用驗證器(請檢查代碼是否符合更好地了解)。 不幸的是,這導致了循環依賴,結果-破壞了整個事情。

我了解正在發生的事情以及原因,但是我找不到解決方法。 我嘗試了堆棧提供的答案,並瀏覽了Google的許多文章,但都沒有走運。 我試過在require之前移動exports ,將我的結構聲明為var以使用提升,在exports之前聲明空結構,然后在之后定義它們,等等。 我知道我可以通過將公共驗證器移動到單獨的文件並將其導入兩個模塊來解決這種情況,但這不是我想要的,因為這並不能完全解決將來的問題,因為我可能需要其他屬性/方法被暴露。 另外-看起來似乎並不正確:ClassA屬性的驗證器應堅持使用ClassA“域”,反之亦然。

現在的代碼。 這是簡化的,但是我正在使用的工作版本:

// ClassA.js:
const { ClassB } = require('./ClassB');

// This prints: ClassA inside ClassB: undefined
console.log('ClassB inside ClassA:', ClassB);

const _validators = {
    // This is validator defined in ClassA...
    property_a: (value) => true,

    // ...And this one is reusing a validator from ClassB
    // I'm getting: TypeError: Cannot read property 'VALIDATORS' of undefined
    property_b: ClassB.VALIDATORS.property_b,
};

exports.ClassA = class ClassA {
    constructor() {
        // Here comes the code defining descriptors for each property 
        // and running the property-specific validator inside 
        // a field setter
    }

    // Expose class-specific validators as class property
    static get VALIDATORS () {
        return _validators;
    }
};
// ClassB.js:
const { ClassA } = require('./ClassA');

console.log('ClassA inside ClassB:', ClassA);

const _validators = {
    // This is validator defined in ClassA...
    property_a: ClassA.VALIDATORS.property_a,

    // ...And this one is reusing a validator from ClassB
    property_b: (value) => true,
};

exports.ClassB = class ClassB {
    constructor() {
        // Here comes the code defining descriptors for each property 
        // and running the property-specific validator inside 
        // a field setter
    }

    // Expose class-specific validators as class property
    static get VALIDATORS () {
        return _validators;
    }
};
// app.js
const { ClassA } = require('./ClassA');
const { ClassB } = require('./ClassB');

console.log(ClassA, ClassB);

由於循環導入,ClassB內的ClassA是undefined (盡管根據我讀過的文章,它應該是{} )在console.log上可見,並導致我得到以下錯誤:

TypeError: Cannot read property 'VALIDATORS' of undefined
    at Object.<anonymous> (/repository/ClassB.js:6:24)

如何重新定義/重新排列代碼以使其正常工作,而又不創建另一個公共文件?

任何幫助,將不勝感激。

我正在使用:Node.js v.11.6.0

我知道我可以通過將公共驗證器移動到一個單獨的文件並將其導入兩個模塊中來解決這種情況,但這不是我想要的。

正是您所需要的。 做吧 沒有什么問題。 在當前的演示代碼中,兩個_validators對象看起來相同,它們的所有屬性都相同-您甚至不需要創建兩個具有不同屬性的共享自定義對象,這些共享對象之外還具有特定的屬性。

另外-看起來似乎並不正確:ClassA屬性的驗證器應堅持使用ClassA“域”,反之亦然。

看起來不對的是, ClassA公開了ClassB.VALIDATORS.property_b ,反之亦然。 你為什么做這個? 這兩類人之間的聯系是否比應有的緊密? 看起來它們都具有完全相同的屬性名稱。

另外,如果property_b將包含應該驗證的Class_B實例,並且您想使用Class_B聲明驗證代碼,則只需給Class_B一個Class_B .validate()方法,然后從您在Class_A文件中定義的屬性驗證器中調用它Class_A

我試過在require之前移動exports ,將我的結構聲明為var以使用提升,還有很多很多。

好吧,如果您看兩個對象文字

const a_validators = {
    property_a: (value) => true,
    property_b: b_validators.property_b,
};
const b_validators = {
    property_b: (value) => true,
    property_a: a_validators.property_a,
};

絕對沒有辦法安排他們的評估順序,以便兩者都能獲得理想的結果。 您必須將它們分開。

另一種解決方案是將它們聲明為半空,並在兩個模塊都已加載時延遲其余部分的初始化。 您可以使用getter進行此操作-覆蓋module.exports而不是在其上創建屬性時,還需要將require()調用放置在getter內。

const _validators = {
    property_a: (value) => true,

    get property_b() {
        const { ClassB } = require('./ClassB');
        return ClassB.VALIDATORS.property_b;
    }
};
// and vice versa

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM