0
我有在ES6這個問題在通天環境

ES6模塊和循環依賴

// A.js 
class A { 
} 
export default new A(); 

// B.js 
import C from './C'; 
class B { 
} 
export default new B(); 

// C.js 
import A from './A'; 
import B from './B'; 
class C { 
    constructor(A, B){ 
     this.A = A; 
     this.B = B; // undefined 
    } 
} 
export default new C(A, B) 

我導入它們是這樣的:

// stores/index.js 
import A from './A'; 
import B from './B'; 
import C from './C'; 

export { 
    A, 
    B, 
    C 
} 

而且從我的應用程序入口點我做的:

import * as stores from './stores'; 

我(希望)預期執行順序是A - >乙 - > C,但實際上它是A-> C-> B.
這是由於模塊B導入了C,所以C模塊在B模塊之前被評估。這在C的設置中產生問題,因爲在那種情況下,B將是undefined

我見過類似的question,但我不確定init函數是否是這裏最好的解決方案,這似乎有點不合理。

問題:在ES6中解決這種循環依賴關係的最佳做法是什麼?它可能適用於不同的環境(Babel,Rollup)?

+0

*預期執行的順序是A - >乙 - > C * - 爲其切入點?如果甚至沒有使用C,爲什麼C在B中導入? – estus

+0

它被使用,這是一個缺少實現細節的例子。我已經更新了添加入口點的問題 – Leonardo

+0

省略的細節在這裏改變了一切。不會有循環依賴,因爲未使用的導入被跳過。考慮提供http://stackoverflow.com/help/mcve。同樣僅僅爲單例使用類是反模式。 – estus

回答

1

有關ES6中循環依賴關係的最佳實踐是什麼?

完全避免它們。如果您不能(或不想)完全避免它們,請將涉及的模塊僅限於使用具有循環依賴性的函數聲明,從不使用導入的值初始化頂級值(常量,變量,類) extends參考)。

什麼可能適用於不同的環境(Babel,Rollup)?

模塊解析和初始化的順序在ES6規範中定義,所以在所有ES6環境中都應該是相同的 - 不管模塊如何加載以及如何解析其標識符。

如何解決這種循環依賴設置?

如果你確實有循環依賴X -> Y -> Z -> … -> X -> …,你需要建立一個起點。假設你想先加載X,雖然它取決於Y,所以你需要確保X從不使用任何導入的值,直到圓圈中的所有模塊都完全初始化。所以你打破了XY之間的圓圈,你需要在Y處啓動導入鏈 - 它將遞歸遍歷依賴關係,直到它停在X之間,因爲它沒有進一步的依賴關係,所以沒有被初始化,所以它會是第一個要評估的模塊。

,你必須遵循那麼規則是總是進口Y進口其他模塊中的任何在圈內之前。如果你甚至有一次不使用這個通用的單一入口點,你的房子會崩潰。

在你的具體的例子,這意味着index.js將需要使用

import A from './A'; 
import C from './C'; // entry point to circular dependencies 
import B from './B'; 
…