標籤:extjs loader success
首先,Loader有幾個重要的屬性
queue: [] 存放所有主檔案類資訊,包括他的依賴檔案資訊,結構如下: [{requires: ‘Seed.view.MainGrid‘ callback: callback // Loader.require(dependencies,function(){});中的function }]注意:所有的動態負載檔案資訊都會被放到隊列中isLoading: 是否在載入numLoadedFiles: 已經載入完成檔案數numPendingFiles: 待負載檔案數seriptsLoading: 正在載入的檔案數isClassFileLoaded: {} Object Storage Service了所有的類以及他們是否已經被載入了
當檔案載入、解析完成會調用回調方法:
if (‘addEventListener‘ in script ) { script.onload = onLoadFn; } else if (‘readyState‘ in script) { // for <IE9 Compatability script.onreadystatechange = function() { if ( this.readyState == ‘loaded‘ || this.readyState == ‘complete‘ ) { onLoadFn(); } }; } else { script.onload = onLoadFn; }
回調方法,之前也有所涉及,如下:
onFileLoaded: function(className, filePath) { var loaded = isClassFileLoaded[className]; // 檔案是否已經被載入過 Loader.numLoadedFiles++; // 已載入數量加1 isClassFileLoaded[className] = true; // 標記檔案被載入過 isFileLoaded[filePath] = true; // In FF, when we sync load something that has had a script tag inserted, the load event may // sometimes fire even if we clean it up and set it to null, so check if we‘re already loaded here. if (!loaded) { // 如果檔案之前沒有被載入過,那麼待載入數減1 Loader.numPendingFiles--; } if (Loader.numPendingFiles === 0) { // 當待載入數為0 Loader.refreshQueue(); } // missingClasses的處理,略 }
當待載入數量為0的時候,執行Loader.refreshQueue(),如下:
refreshQueue: function() { var ln = queue.length, i, item, j, requires; // When the queue of loading classes reaches zero, trigger readiness if (!ln && !Loader.scriptsLoading) { // ,遞迴的結束條件:載入隊列為空白 return Loader.triggerReady(); // triggerReady見下面 } for (i = 0; i < ln; i++) { // 迴圈隊列中的每一個對象 item = queue[i]; if (item) { requires = item.requires; // Don‘t bother checking when the number of files loaded // is still less than the array length if (requires.length > Loader.numLoadedFiles) { continue; } // Remove any required classes that are loaded for (j = 0; j < requires.length; ) { if (Manager.isCreated(requires[j])) { // 如果某個item的依賴類A已經被建立了,則從item的require中移除他 // Take out from the queue arrayErase(requires, j, 1); } else { j++; } } // If we‘ve ended up with no required classes, call the callback if (item.requires.length === 0) { // 當某個類的所有依賴檔案都已經被載入,那麼從隊列中移除該item arrayErase(queue, i, 1); item.callback.call(item.scope); Loader.refreshQueue();// 遞迴 break; } } } return Loader; }
refreshQueue()方法的作用,是不停的迴圈檢測,直到所有的類都被載入、執行、建立,之後調用triggerReady()方法,如下:
triggerReady: function() { var listener, refClasses = usedClasses; if (Loader.isLoading) { Loader.isLoading = false; if (refClasses.length !== 0) { // 載入用use關鍵字引用的路徑 // Clone then empty the array to eliminate potential recursive loop issue refClasses = refClasses.slice(); usedClasses.length = 0; // this may immediately call us back if all ‘uses‘ classes // have been loaded Loader.require(refClasses, Loader.triggerReady, Loader); return Loader; } } Ext.Array.sort(readyListeners, comparePriority);// listener排序 // this method can be called with Loader.isLoading either true or false // (can be called with false when all ‘uses‘ classes are already loaded) // this may bypass the above if condition while (readyListeners.length && !Loader.isLoading) { // 逐個調用回調方法 // calls to refreshQueue may re-enter triggerReady // so we cannot necessarily iterate the readyListeners array listener = readyListeners.shift(); listener.fn.call(listener.scope); } return Loader; }
從這裡看出:use關鍵字依賴的類,要等其他關鍵字依賴的類都載入成功之後才載入。
本文出自 “技術人生” 部落格,請務必保留此出處http://wangyuelucky.blog.51cto.com/1011508/1604695
extjs loader success callback源碼