使用导出的Singleton类防止循环依赖

时间:2018-02-02 21:44:18

标签: javascript ecmascript-6 circular-dependency

我对构建HTML5游戏时遇到的情况有疑问,导致难以管理循环依赖。

我完全理解为什么会发生循环依赖以及它在何处发生。但是,我似乎无法找到一种方便的方法来解决它,因此我认为我的逻辑/方法存在根本缺陷。

以下是一些背景信息。

我有一个游戏,它有一个名为Game.js的单一入口点(使用Webpack编译)。我有一个基本的事件管理器,允许两个函数on(key, callback)fire(key, parameters)

事件管理器只是创建一个对象,将提供的on键设置为一个属性,其数组值填充了​​注册到该键的任何callback函数。调用fire方法时,将检索该属性,并调用其数组值中定义的所有函数。

我正在尝试做什么

我希望能够在Game.js上实例化事件管理器并导出其他类可以导入的Game实例,然后将回调注册到Game实例事件管理器。 / p>

class Game {

    constructor() {
        this.events = new EventManager();

        window.addEventListener('resize', this.resize.bind(this));
    }

    resize(event) {
       if(window.innerWidth < window.innerHeight) {
          this.events.fire('orientation-change', 'vertical');
       } else {
          this.events.fire('orientation-change', 'horizontal');
       }
    }

}

export default new Game();

然后,例如Button类可能需要响应Game触发的方向更改事件。请注意,以上只是事件管理器可以发起事件的情况的示例,但这种情况可能是任何事情。

import Game from '../core/Game';    

class Button {

    constructor() {
       Game.events.on('orientation-change', this.reorient.bind(this));
    }

    reorient() {
        // ...
    }

}

export default Button;

上面的类是一个名为Button的UI组件,需要知道orientation-change事件何时被触发,请再次注意,此事件可能是任何

有什么问题?

上面没有什么看起来特别错误,因为Game.js是入口点,在某些时候创建Button的实例,无论是直接在Game.js还是通过另一个类,通过Game.js实例化,这当然会导致循环依赖,因为即使不是直接依赖,Game导入ButtonButton导入Game

我尝试了什么

我发现有两种主要的解决方案可以工作(在某种程度上)。第一个是在Button的构造函数中使用间隔检查Game的值来等待导出可用,如下所示:

import Game from '../core/Game';

class Button {

    constructor() {
        let check = setInterval(() => {
            if(Game !== undefined) {
                Game.events.on('orientation-change', this.reorient.bind(this));

                clearInterval(check);
            }
        }, 100);
    }

    reorient() {
        // ...
    }

}

export default Button;

这通常会在一次迭代中解决。

第二种解决方案是使用依赖注入并在实例化时传递Game to Button的引用,这也很有用,但是每个类不得不反复执行此操作的前景似乎不直观。间隔检查工作正常,但似乎很hacky。

我觉得我完全错过了一些东西,而且解决方案并不困难,因为我正在制作它。

感谢您提供任何帮助。

0 个答案:

没有答案
相关问题