seaJS循環依賴的解決原理

seajs模塊的六個狀態。javascript

var STATUS = { 
  'FETCHING': 1, // The module file is fetching now. 模塊正在下載中 
  'FETCHED': 2, // The module file has been fetched. 模塊已下載 
  'SAVED': 3, // The module info has been saved. 模塊信息已保存 
  'READY': 4, // All dependencies and self are ready to compile. 模塊的依賴項都已下載,等待編譯 
  'COMPILING': 5, // The module is in compiling now. 模塊正在編譯中 
  'COMPILED': 6 // The module is compiled and module.exports is available. 模塊已編譯 
}html

咱們假設a.js的代碼:java

define(function(require, exports, module){
    var b = require('./b.js');
    //......
});

b.js的代碼:函數

define(function(require, exports, module){
    var a = require('./a.js');
    //......
});

循環依賴的概念:seajs在使用a模塊時,會先下載a模塊,a模塊下載時,a模塊的狀態是FETCHING,下載好了以後,a模塊的狀態是FETCHED,而後解析a模塊,這時會從a模塊的回調函數中尋找a模塊依賴的模塊,這裏a模塊依賴的模塊是b模塊。這時,a模塊的狀態變成了SAVED,而後去下載b模塊,這時b模塊的狀態是FETCHING,下載好了以後,b模塊的狀態是FETCHED,而後解析b模塊,這時會從b模塊的回調函數中尋找b模塊依賴的模塊,這裏b模塊依賴的模塊是a模塊。這裏就產生了循環依賴的問題。fetch

seajs裏面是如何解決這個問題的呢?ui

此問題,很是重要,不信,你等着看。spa

seajs中處理這個問題的第一步:htm

在a模塊的回調函數中尋找a模塊依賴的模塊後(這時a模塊的狀態是SAVED了,會判斷a模塊所依賴的模塊是否跟本身有循環依賴的關係,若是有,就不去下載,seajs是經過getPureDependencies方法進行判斷的,因爲這時b模塊還不存在於cachedModules中,因此這裏不會檢查出a與b有循環依賴的關係。blog

所以,去下載b模塊,下載好了以後,b模塊的狀態是FETCHED,而後解析b模塊,這時就會從b模塊的回調函數中尋找b模塊依賴的模塊,這裏檢查出來了是a模塊,這時b模塊的狀態變成了SAVED的。而後判斷a模塊是否與本身(b模塊)循環依賴。因爲此時a模塊存在,而且狀態是SAVED,這時就會檢查出來了有依賴,所以b模塊的狀態就會直接變成了READY。ip

這時,a模塊的狀態就會變成READY(若是a模塊還依賴其餘的模塊,好比c模塊,那麼等c模塊變成READY後,a模塊纔會變成READY狀態)。這時,就會去編譯a模塊,a模塊的狀態是COMPILING,編譯過程,其實就是執行a模塊的回調函數,(若是這裏a模塊依賴的是c模塊,這時,就會執行c模塊的回調函數,也就是編譯c模塊,編譯結束後,c模塊變成了COMPILED),緊接着,a模塊變成COMPILED。

可是,這裏依賴的是b模塊,所以,在執行a模塊的回調函數時(在編譯a模塊時),會執行b模塊的回調函數,也就是編譯b模塊,等編譯結束,b模塊變成了COMPILED,緊接着a模塊就變成了COMPILED。

循環依賴的分析到此結束,你們能夠跟着個人另外一篇博客一塊兒分析。

http://www.cnblogs.com/chaojidan/p/4126647.html

 

 

 

 

 

加油! 

相關文章
相關標籤/搜索