[muzzik讨论]:如何更优雅的解决循环引用?

你这种使用方式,比较奇怪。没试过,不过你可以试试我的方式。

有些方式会让这个模块方案头疼的。
比如:注入对象的实例
这个对象实例在实例构造期间就引用了模块,这个会报错

declare global {
    interface IModuleMap {
        bag: BagModule
    }
}
export class BagModule implements egf.IModule {
    key: string = "bag";
    hero = m.hero.getHeroById(1);//这样会出问题
    onInit() {
        //所有模块实例注入之后
    }
    onAfterInit() {
        //所有模块初始化onInit调用之后
    }
    getItemById(id: number) {
        return { id: id, num: 2 };
    }
}

比如:注入对象的构造函数

//A.ts
declare global {
    interface IModuleMap {
        A: typeof A
    }
}
export class A  {
    static b = new m.B();//静态变量调用了
    doSomething(){
    }
}

那么你是把模块依赖的枚举,常量,或者自定义的数据类型放在一个单独的脚本中吗?这样不太方便记忆与使用

不用啊,这个时候就体现declare的作用了,只需要单独在模块的文件顶部写一下就可以了。ts会做类型合并
比如

//A.ts
declare global {
    interface IModuleMap {
        A: typeof A
    }
}
//BagModule.ts
declare global {
    interface IModuleMap {
        bag: BagModule
    }
}
//HeroModule.ts
declare global {
    interface IModuleMap {
        hero: HeroModule
    }
}
//B.ts
declare global {
    interface IModuleMap {
        B: typeof B
    }
}
//ts会将类型合并为
declare global {
    interface IModuleMap {
        B: typeof B
        A: typeof A
        hero: HeroModule
        bag: BagModule
    }
}

在app.loadModule()时,参数都有类型提示,自动提示传入什么字符串才是合法的
image
在调用m.B 时也有提示

1赞

经过和你的讨论,我发现,虽然我知道这个模块机制有很多用处,但对于没有接触和用过的需要很多示例才能解释清楚有哪些用处

毕竟不是作者,用了那么久。

2赞

我理解declare合并,我想你指的是分脚本放置,然后利用declare合并来使用吧,这样的确可以解决这个问题,也需要将依赖的东西全部注册,我有空试试

感谢回复 :+1:

mark 有空研究研究

1赞

我只能说你们nb

继续用前端的思路折腾游戏吧, 希望你们头发茂密, 游戏工业几十年的积累, 现在大家要在web用前端思路重建。
加油, 未来是你们的, 也是我们的。

5赞

大佬 求救啊 我也因为继承的循环引用出现这个问题

控制好代码结构,基类不用引用子类,基层不能引用顶层,实在用到了,就用动态加载,还有画好 UML 类图可以比较清晰的整理

还有个方法,在执行循环引用的脚本之前,在前面的脚本里引用一下这个循环引用的类,类似于让他提前加载,

这样的方式我称为屎山代码

你可以写一个无意义的方法,甚至是一个空方法,类似这样image
效率高并且方便,哪里屎山了.

  1. 无意义
  2. 子子孙孙无穷尽,这只不过是转移矛盾,不是解决矛盾,当转移之后又和当前的脚本循环引用是不是又得转移

我们最迟会在 3.9 解决 @property decorator 带来的循环依赖

roadmap排期更新过了吗???

等今年的预算定下来后会再确认一次今年的 roadmap

个人还未遇到过麻烦的循环依赖,
大部分情况只需要

// 大约是 declare module 的简化方案
import type {A} from 'a'

至于两个 @property 循环引用, 一定是设计不合理… 只能用 @type(Node) 替代