了解ES6中的循环依赖关系

时间:2017-06-02 12:30:38

标签: javascript ecmascript-6

我正在尝试创建一种API。出于这个原因,我尝试导入导入调用来自的文件的主文件(暴露API),包括导出!

混淆?大!

项目结构:

/
/src
/src/js
/src/js/modules
/src/js/modules/moduleA/index|actions|components|selectors
/src/js/modules/moduleB/index|actions|components|selectors
/src/js/modules/moduleC/index|actions|components|selectors

请参阅下面的示例,其中我公开了一个无效的循环依赖项!

所以,这是模块化公开API的方式(在模块本身外部导出时很容易):

// src/modules/foobar/index.js
import * as actions from './actions'
import * as components from './components'
import * as containers from './containers'
import * as constants from './constants'
import reducer from './reducer'
import * as selectors from './selectors'
export default { actions, components, containers, constants, reducer, selectors }

这是导入:

// src/modules/foobar/containers/index.js
import API from '../index.js'
// this is undefined
console.log('API', API)

目标?

ModuleAPI.actions.foobar()
ModuleAPI.containers.foobar()

虽然我可以看到它可能是一种不好的做法(老实说,似乎常识不可能导入文件)我想知道为什么这是不可能的!

2 个答案:

答案 0 :(得分:2)

完全可以像这样导入顶级模块。在容器模块初始化期间,不可能同步使用它。会发生什么基本上是

load foobar/index.js
initialise foobar/index.js:
    load foobar/containers/index.js
    initialise foobar/containers/index.js:
        load foobar/index.js
        it's already getting initialised so don't wait
        set up scope
        execute module code: `API` is still undefined in the log statement
    finish initialisation of foobar/containers/index.js
    set up scope
    execute module code: `API` is getting defined now
finish initialisation of foobar/index.js

因此,只要您将console.log(API)放入函数并稍后调用它,它就会起作用。请注意,对于循环依赖关系,您需要特别注意首先加载顶级模块以获得一致的评估顺序。

答案 1 :(得分:0)

好吧,这更多是一个元哲学问题:您的模块依赖性实际上变成了循环图,而不是DAG /树,因此实际上无法通过拓扑排序and this is known as a very hard problem调度模块的加载顺序。 / p>