如何使用工厂函数解决ES6模块中的循环依赖关系?

时间:2017-07-29 00:10:50

标签: module ecmascript-6 factory

我想在我的src/core/Chessman.js文件中写下这样的内容:

import King from './chessmen/King'

class Chessman {
  static factory(side, quality) {
    switch(quality) {
      case 'king' : return new King(side) break
      // ... other qualities
    }

    constructor(side) { this.side = side }

    cast(position, ref) { }

    run(position, startRef, endRef) {}
  }

并在我的src/core/chessmen/King.js文件中:

import Chessman from '../Chessman'

class King extends Chessman {

  constructor(side) {
    super(side)
    this.iterative = false // true for Queens, Rooks and Bishop
    this.directions = [
      'up', 'up+right', 'right', 'right+down', 
      'down', 'down+left', 'left', 'left+top'
    ]
  }

  // overrides parent behavior
  cast(position, ref) {}
  run(position, startRef, endRef) {}
}

但遗憾的是,我得到了Karma,jasmine和babel的错误(在测试时)

  

TypeError:超级表达式必须为null或函数,而不是未定义     在src / core / chessmen / King.js:57

目前King.js中没有第57行!

2 个答案:

答案 0 :(得分:2)

您有循环依赖性错误。根据您向我们展示的内容,请考虑以下步骤:

  1. Chessman.js开始加载
  2. 它会暂停执行,因此可以加载其依赖项。
  3. King.js开始加载,因为它是一个依赖项。
  4. King.js因为class King extends Chessman运行而被抛出,但Chessman尚未设置,因为它在第2步暂停了
  5. 将工厂功能移动到自己的文件会更好,以避免周期性依赖。 JS中唯一安全的循环依赖项是模块本身初始化时不需要的依赖项。由于class extends X在模块初始化时运行,因此循环不安全。

    如果这是您唯一的课程,您可以编写您的应用,以便在King.js之前导入Chessman.js,但考虑到您对工厂的使用以及您的命名方案,我认为还有其他棋子。由于每个棋子类都会触发此问题,因此无法以正确的顺序导入它们。通过将工厂功能移出Chessman.js来避免此问题是解决此问题的唯一方法。

答案 1 :(得分:0)

如果您想拥有工厂,而不是直接将其保存在基类模块中,请将其移至其自己的模块 - chessman.factory.js。在那里,做任何Chessman.factory在方法或事物中做的事情。这样chessman.js模块就不必了解需要自己的模块,