如何使用RequireJS / AMD处理循环依赖? [英] How to handle circular dependencies with RequireJS/AMD?

查看:142
本文介绍了如何使用RequireJS / AMD处理循环依赖?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的系统中,我在浏览器中加载了许多类,每个文件在开发过程中都是单独的文件,并连接在一起进行生产。当它们被加载时,它们在全局对象上初始化一个属性,这里是 G ,如下例所示:

In my system, I have a number of "classes" loaded in the browser each a separate files during development, and concatenated together for production. As they are loaded, they initialize a property on a global object, here G, as in this example:

var G = {};

G.Employee = function(name) {
    this.name = name;
    this.company = new G.Company(name + "'s own company");
};

G.Company = function(name) {
    this.name = name;
    this.employees = [];
};
G.Company.prototype.addEmployee = function(name) {
    var employee = new G.Employee(name);
    this.employees.push(employee);
    employee.company = this;
};

var john = new G.Employee("John");
var bigCorp = new G.Company("Big Corp");
bigCorp.addEmployee("Mary");

我没有使用自己的全局对象,而是考虑让每个类都有自己的 AMD模块,基于 James Burke的建议

Instead of using my own global object, I am considering to make each class its own AMD module, based on James Burke's suggestion:

define("Employee", ["Company"], function(Company) {
    return function (name) {
        this.name = name;
        this.company = new Company(name + "'s own company");
    };
});
define("Company", ["Employee"], function(Employee) {
    function Company(name) {
        this.name = name;
        this.employees = [];
    };
    Company.prototype.addEmployee = function(name) {
        var employee = new Employee(name);
        this.employees.push(employee);
        employee.company = this;
    };
    return Company;
});
define("main", ["Employee", "Company"], function (Employee, Company) {
    var john = new Employee("John");
    var bigCorp = new Company("Big Corp");
    bigCorp.addEmployee("Mary");
});

问题在于之前,员工和公司之间没有申报时间依赖关系:你可以把你想要的任何顺序的声明,但现在,使用RequireJS,这引入了一个依赖,这里(故意)循环,所以上面的代码失败。当然,在 addEmployee()中,添加第一行 var Employee = require(Employee); 将< a href =http://requirejs.org/docs/api.html#circular =nofollow noreferrer>让它工作,但我觉得这个解决方案不如不使用RequireJS / AMD需要我,开发人员,要知道这个新创建的循环依赖关系,并做一些事情。

The issue is that before, there was no declare-time dependency between Employee and Company: you could put the declaration in whatever order you wanted, but now, using RequireJS, this introduces a dependency, which is here (intentionally) circular, so the above code fails. Of course, in addEmployee(), adding a first line var Employee = require("Employee"); would make it work, but I see this solution as inferior to not using RequireJS/AMD as it requires me, the developer, to be aware of this newly created circular dependency and do something about it.

有没有更好的方法来解决RequireJS / AMD的这个问题,或者我使用RequireJS / AMD做它不是为什么设计的?

Is there a better way to solve this problem with RequireJS/AMD, or am I using RequireJS/AMD for something it was not designed for?

推荐答案

这确实是AMD格式的限制。你可以使用导出,这个问题就消失了。我发现导出很难看,但是常规的CommonJS模块解决了这个问题:

This is indeed a restriction in the AMD format. You could use exports, and that problem goes away. I find exports to be ugly, but it is how regular CommonJS modules solve the problem:

define("Employee", ["exports", "Company"], function(exports, Company) {
    function Employee(name) {
        this.name = name;
        this.company = new Company.Company(name + "'s own company");
    };
    exports.Employee = Employee;
});
define("Company", ["exports", "Employee"], function(exports, Employee) {
    function Company(name) {
        this.name = name;
        this.employees = [];
    };
    Company.prototype.addEmployee = function(name) {
        var employee = new Employee.Employee(name);
        this.employees.push(employee);
        employee.company = this;
    };
    exports.Company = Company;
});

否则,您在邮件中提到的要求(员工)也会有效。

Otherwise, the require("Employee") you mention in your message would work too.

一般而言,对于模块,您需要更多地了解循环依赖关系,AMD与否。即使在纯JavaScript中,您也必须确保在示例中使用类似G对象的对象。

In general with modules you need to be more aware of circular dependencies, AMD or not. Even in plain JavaScript, you have to be sure to use an object like the G object in your example.

这篇关于如何使用RequireJS / AMD处理循环依赖?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆