如何在require.js中正确解析循环依赖

时间:2013-10-10 20:24:39

标签: javascript requirejs amd

我有以下模块配置: Global -> Collections -> Favorites(全局需要集合,集合需要收藏夹)。

同时Favorites还需要Global模块(对于其他属性)。

示例代码:

define("global", ["collections"], function(Collections) {
    console.log("Defining global");

    var Global = {
        env: "home",
        collections: Collections
    };

    return Global;
});
define("collections", ["favorites"], function(Favorites) {
    console.log("Defining collections");

    var collections = {
        likes: function() {},
        favorites: Favorites
    };

    return collections;
});
define("favorites", ["global"], function(Global) {
    console.log("Defining favorites");

    var Favorites = function(name) {
        console.log(Global.env)
        this.name = name;
    };
    return Favorites;
});

require(["global"], function(Global) {
    console.log("global", Global);
    console.log("collections", Global.collections);
    console.log("favorites", Global.collections.favorites);

    var Favorites = Global.collections.favorites;
    Favorites();
});

我也为这种情况创建了jsfiddle:http://jsfiddle.net/NBSzC/

正如我们尝试从env读取值undefined)时,此代码会产生错误。

在StackOverflow上,在同一案例中还有其他有用的票证:How to handle circular dependencies with RequireJS/AMD?

使用它我能够“工作”,请检查以下小提琴:http://jsfiddle.net/NBSzC/1/

这里的问题在于我必须使用

console.log(Global.Global.env)

因为原始Global现在指向出口对象,我们已经设置了Global to Global的链接。

我们也可以在全局模块中关注,但我相信这是另一个黑客:

_.extend( exports, Global );

在相应的链接中根本没有这样的问题,不确定我做错了什么。

1 个答案:

答案 0 :(得分:1)

我觉得循环依赖是代码组织遭受的“嗅觉”。

在你的情况下,我认为你需要全局变量中的collections字段。如果某些东西取决于集合,为什么不直接询问集合模块呢?

在这种情况下,依赖项将是:Collections→Favorites→Globals(但Globals不指向收藏夹,因此圆圈被破坏)。

然后,如果您确实需要从头开始加载所有内容,则可以修改require()调用:

require(["global","collections"], function(Global,Collections) { ...

或者定义一个需要所有内容的bootstrap模块,并要求:

define("bootstrap",["global","collections","favorites"], function(...) { ...
require("bootstrap", ...)

当然,我没有项目的所有细节,因此解决方案可能会有所不同。但仍然主要的一点是循环依赖是一种气味。