2013-10-10 77 views
2

我有以下模塊配置: Global -> Collections -> Favorites(全局需要集合,集合需要收藏夾)。如何正確解決require.js中的循環依賴關係

同時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這種情況:當我們試圖讀取undefined值(envhttp://jsfiddle.net/NBSzC/

正如你可以看到這個代碼產生錯誤。

這裏StackOverflow上存在對同一案件的其他有用票:How to handle circular dependencies with RequireJS/AMD?

使用它,我能夠讓它「工作」,請檢查下面的小提琴:http://jsfiddle.net/NBSzC/1/

而且這裏的問題是我不得不使用

console.log(Global.Global.env) 

作爲原始Global現在指向導出對象,並且我們已經建立了Global as Global的鏈接。

我們也做了全局模塊下面,但我相信這是另一個黑客:

_.extend(exports, Global); 

在相應的鏈接沒有這樣的問題都沒有,不知道我做錯了。

回答

1

我有這樣的感覺,即循環依賴是代碼組織遭受的「氣味」。

在你的情況下,我會爭辯說,你做不是需要全局的collections字段。如果某件事取決於集合,爲什麼不直接詢問集合模塊?

在這種情況下,依賴關係將爲:集合→收藏→全局(但全局不會指向收藏,因此圓被破壞)。

然後,如果你真的需要加載一切從一開始,你可以修改require()電話:

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

或定義所需要的所有的引導模塊,並要求:

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

當然,我沒有你的項目的所有細節,所以解決方案可能會有所不同。但仍然主要的一點是循環依賴是一種氣味。