ES6 循环依赖。实施依赖中心
ES6 circular dependency. Implementing dependency hub
我发现了很多关于循环依赖的文章,它表明了项目中的 design/architecture 缺陷。在大多数情况下,可以通过稍微重构您的 classes.
轻松修复它
在这个例子中,我试图为依赖项创建一个中心。这是一个 classes 的库,可以被不同的项目导入。目标是在主要 class 中有 getters,这将 return 一个依赖实例。这个实例必须是一个单例,并且它存储在主 class' 依赖项中,下次如果有人调用 getter - 它会 return 那个 class 的相同实例.
代码如下所示:
// deps
import { DepA } from './dep-a';
import { DepB } from './dep-b';
const depsKey = '__MY_DEPS__';
class Deps {
dependencies = {};
get depA() {
return this.getDependency('depA', DepA);
}
get depB() {
return this.getDependency('depB', DepB);
}
bind(key, value) {
this.dependencies[key] = value;
}
getDependency(key, serviceClass) {
let service = this.dependencies[key];
if (!service && !!serviceClass) {
// if instance is not created yet, we instantiate the class and put instance in the dependencies
service = new serviceClass();
this.bind(key, service);
}
return service;
}
}
export const deps = (() => {
window[depsKey] = window[depsKey] || new Deps();
return window[depsKey];
})();
// dep-a
import { deps } from './deps';
export class DepA {
methodA() {
console.log(deps.depB);
}
}
// dep-b
import { deps } from './deps';
export class DepB {
methodB() {
console.log(deps.depA);
}
}
如您所见 - 这会产生循环依赖问题,因为 class Deps 在其 getter 中使用 classes DepA 和 DepB 来创建这些 classes 如果它不存在。 classes DepA 和 DepB 使用 Deps 的实例通过其 getters 相互检索。
希望这个解释不会很繁琐
任何人都可以建议我需要进行哪些更改以摆脱此处的循环依赖,但要保持通过 Deps class(deps 实例)访问单例的想法?
我的建议是:
a-singleton.js
import { DepA } from './dep-a';
let singleton;
export function getA() {
if (!singleton) {
singleton = new DepA();
}
return singleton;
}
b-singleton.js
import { DepB } from './dep-b';
let singleton;
export function getB() {
if (!singleton) {
singleton = new DepB();
}
return singleton;
}
然后在任何需要这些单例的地方,您可以导入文件并调用函数来获取单例。
根据这些 类 的作用以及它们 how/when 相互引用,您也可以直接执行 export default new DepA()
,但取决于它们如何相互引用,以及引用的程度他们需要在实例化时执行,我在这里展示的惰性方法可能更好或必要。
我发现了很多关于循环依赖的文章,它表明了项目中的 design/architecture 缺陷。在大多数情况下,可以通过稍微重构您的 classes.
轻松修复它在这个例子中,我试图为依赖项创建一个中心。这是一个 classes 的库,可以被不同的项目导入。目标是在主要 class 中有 getters,这将 return 一个依赖实例。这个实例必须是一个单例,并且它存储在主 class' 依赖项中,下次如果有人调用 getter - 它会 return 那个 class 的相同实例.
代码如下所示:
// deps
import { DepA } from './dep-a';
import { DepB } from './dep-b';
const depsKey = '__MY_DEPS__';
class Deps {
dependencies = {};
get depA() {
return this.getDependency('depA', DepA);
}
get depB() {
return this.getDependency('depB', DepB);
}
bind(key, value) {
this.dependencies[key] = value;
}
getDependency(key, serviceClass) {
let service = this.dependencies[key];
if (!service && !!serviceClass) {
// if instance is not created yet, we instantiate the class and put instance in the dependencies
service = new serviceClass();
this.bind(key, service);
}
return service;
}
}
export const deps = (() => {
window[depsKey] = window[depsKey] || new Deps();
return window[depsKey];
})();
// dep-a
import { deps } from './deps';
export class DepA {
methodA() {
console.log(deps.depB);
}
}
// dep-b
import { deps } from './deps';
export class DepB {
methodB() {
console.log(deps.depA);
}
}
如您所见 - 这会产生循环依赖问题,因为 class Deps 在其 getter 中使用 classes DepA 和 DepB 来创建这些 classes 如果它不存在。 classes DepA 和 DepB 使用 Deps 的实例通过其 getters 相互检索。
希望这个解释不会很繁琐
任何人都可以建议我需要进行哪些更改以摆脱此处的循环依赖,但要保持通过 Deps class(deps 实例)访问单例的想法?
我的建议是:
a-singleton.js
import { DepA } from './dep-a';
let singleton;
export function getA() {
if (!singleton) {
singleton = new DepA();
}
return singleton;
}
b-singleton.js
import { DepB } from './dep-b';
let singleton;
export function getB() {
if (!singleton) {
singleton = new DepB();
}
return singleton;
}
然后在任何需要这些单例的地方,您可以导入文件并调用函数来获取单例。
根据这些 类 的作用以及它们 how/when 相互引用,您也可以直接执行 export default new DepA()
,但取决于它们如何相互引用,以及引用的程度他们需要在实例化时执行,我在这里展示的惰性方法可能更好或必要。