复杂的TypeScript循环依赖问题

时间:2019-11-29 18:12:05

标签: angular typescript circular-dependency

我的Angular应用程序的数据模型中的依赖结构非常复杂。

在抽象形式下,它看起来像这样(A-> B表示“ A导入B”):

enter image description here

通过这种结构,我得到了许多循环依赖关系,这对我来说很难解决。我已经尝试应用提到的解决方案here:我尝试使用internal.ts文件并导出该文件中的所有类。导入任何类时,我再次从./internal.ts文件中导入了它们。

仍然,问题仍然存在。唯一更改的是错误消息的形式:

来自

Circular dependency detected: C.ts -> D.ts -> E.ts -> C.ts

Circular dependency detected: C.ts -> internal.ts -> C.ts
Circular dependency detected: D.ts -> internal.ts -> D.ts
Circular dependency detected: E.ts -> internal.ts -> E.ts

还有其他方法可以解决这样的问题吗?

1 个答案:

答案 0 :(得分:0)

linked article中提出的解决方案并未消除循环依赖关系–它只是避免了通过仔细控制装载顺序而可能造成的任何灾难性影响。引用:

  

之所以能够解决我们的问题,是:我们现在拥有完全的控制权   根据模块的加载顺序。无论进口顺序如何   internal.js是我们的模块加载顺序。

循环依赖仅是一个问题,因此,只有当您有模块在加载时立即评估时,模块加载顺序才真正重要–即,导入的值将在模块的主体中​​使用模块:

// Foo.js
import { Bar } from "./Bar"

export class Foo {
  getBarClass() {
    return Bar;
  }
}


// Bar.js
import { Foo } from "./Foo"

console.log(Foo.name);           // Foo eval'ed on load :(
export const fooClass = Foo;     // Foo eval'ed on load :(

export class Bar extends Foo {   // Foo eval'ed on load :(
  static fooClass = Foo;         // Foo eval'ed on load :(
  fooClass = Foo;                // Eval'ed only on new Bar()

  static getFooClass() {        
    return Foo;                  // Eval'ed only on Bar.getFooClass()
  }

  getFooClass() {                
    return Foo;                  // Eval'ed only on someBar.getFooClass()
  }
}

在此示例中, Foo.js 在加载时不访问Bar,只有在调用getBarClass之后才访问。另一方面, Bar.js 在加载时确实多次访问了导入的Foo。因此,必须先加载 Bar.js

一旦不再在加载时立即访问导入,循环依赖就不再是问题:

// execute in next tick
setImmediate(() => console.log(Foo.name));

// wrap in function
export const getFooClass = () => Foo;

// wrap in function
export const getBarClass = () => {
  return class Bar extends Foo {
    static fooClass = Foo;
    fooClass = Foo;
  };
};

当然,这些用于延迟评估的解决方案看起来很难看,因此最终您可能仍要遵循精心协调的加载顺序。