主要涉及到Ext.js Inventory.js ClassManager.js Class.js Loader.js Boot.js
在ClasManager.js的Ext.create中
Ext.syncRequire(name); // 加载类的js
Loader.js 中
syncRequire: function () { var wasEnabled = Loader.syncModeEnabled; Loader.syncModeEnabled = true; var ret = Loader.require.apply(Loader, arguments); Loader.syncModeEnabled = wasEnabled; return ret; },
require: function (expressions, fn, scope, excludes) { if (excludes) { return Loader.exclude(excludes).require(expressions, fn, scope); } var classNames = Manager.getNamesByExpression(expressions); return Loader.load(classNames, fn, scope); },
load: function (classNames, callback, scope) { if (callback) { if (callback.length) { // If callback expects arguments, shim it with a function that will map // the requires class(es) from the names we are given. callback = Loader.makeLoadCallback(classNames, callback); } callback = callback.bind(scope || Ext.global); } var state = Manager.classState, missingClassNames = [], urls = [], urlByClass = {}, numClasses = classNames.length, url, className, i, numMissing; for (i = 0; i < numClasses; ++i) { className = Manager.resolveName(classNames[i]); if (!Manager.isCreated(className)) { missingClassNames.push(className); if (!state[className]) { urlByClass[className] = Loader.getPath(className); urls.push(urlByClass[className]); } } } // If the dynamic dependency feature is not being used, throw an error // if the dependencies are not defined numMissing = missingClassNames.length; if (numMissing) { Loader.missingCount += numMissing; Manager.onCreated(function () { if (callback) { Ext.callback(callback, scope, arguments); } Loader.checkReady(); }, Loader, missingClassNames); if (!_config.enabled) { Ext.raise("Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. " + "Missing required class" + ((missingClassNames.length > 1) ? "es" : "") + ": " + missingClassNames.join(', ')); } if (urls.length) { Loader.loadScripts({ url: urls, // scope will be this options object so we can pass these along: _classNames: missingClassNames, _urlByClass: urlByClass }); } else { // need to call checkReady here, as the _missingCoun // may have transitioned from 0 to > 0, meaning we // need to block ready Loader.checkReady(); } } else { if (callback) { callback.call(scope); } // need to call checkReady here, as the _missingCoun // may have transitioned from 0 to > 0, meaning we // need to block ready Loader.checkReady(); } if (Loader.syncModeEnabled) { // Class may have been just loaded or was already loaded if (numClasses === 1) { return Manager.get(classNames[0]); } } return Loader; },
/** * This is an internal method that delegate content loading to the * bootstrap layer. * @private * @param params */ loadScripts: function(params) { var manifest = Ext.manifest, loadOrder = manifest && manifest.loadOrder, loadOrderMap = manifest && manifest.loadOrderMap, options; ++Loader.scriptsLoading; // if the load order map hasn't been created, create it now // and cache on the manifest if (loadOrder && !loadOrderMap) { manifest.loadOrderMap = loadOrderMap = Boot.createLoadOrderMap(loadOrder); } // verify the loading state, as this may have transitioned us from // not loading to loading Loader.checkReady(); options = Ext.apply({ loadOrder: loadOrder, loadOrderMap: loadOrderMap, charset: _config.scriptCharset, success: Loader.onLoadSuccess, failure: Loader.onLoadFailure, sync: Loader.syncModeEnabled, _classNames: [] }, params); options.userScope = options.scope; options.scope = options; Boot.load(options); },
在Boot.js中
load: function (request) { //<debug> // _debug("Boot.load called"); //</debug> var request = new Request(request); if (request.sync || Boot.syncMode) { return Boot.loadSync(request); } // If there is a request in progress, we must // queue this new request to be fired when the current request completes. if (Boot.currentRequest) { //<debug> // _debug("current active request, suspending this request"); //</debug> // trigger assignment of entries now to ensure that overlapping // entries with currently running requests will synchronize state // with this pending one as they complete request.getEntries(); Boot.suspendedQueue.push(request); } else { Boot.currentRequest = request; Boot.processRequest(request, false); } return Boot; },
loadSync: function() { var me = this; me.fetch({ async: false, complete: function (response) { me.onContentLoaded(response); } }); me.evaluate(); me.notifyRequests(); },
fetch: function (req) { var url = this.getLoadUrl(), async = !!req.async, complete = req.complete; Boot.fetch(url, complete, this, async); },
最终网络通讯在这
fetch: function(url, complete, scope, async) { async = (async === undefined) ? !!complete : async; var xhr = new XMLHttpRequest(), result, status, content, exception = false, readyStateChange = function () { if (xhr && xhr.readyState == 4) { status = (xhr.status === 1223) ? 204 : (xhr.status === 0 && ((self.location || {}).protocol === 'file:' || (self.location || {}).protocol === 'ionp:')) ? 200 : xhr.status; content = xhr.responseText; result = { content: content, status: status, exception: exception }; if (complete) { complete.call(scope, result); } xhr.onreadystatechange = emptyFn; xhr = null; } }; if (async) { xhr.onreadystatechange = readyStateChange; } try { //<debug> // _debug("fetching " + url + " " + (async ? "async" : "sync")); //</debug> xhr.open('GET', url, async); xhr.send(null); } catch (err) { exception = err; readyStateChange(); return result; } if (!async) { readyStateChange(); } return result; }, notifyAll: function(entry) { entry.notifyRequests(); } };
complete函数定义在这
onContentLoaded: function (response) { var me = this, status = response.status, content = response.content, exception = response.exception, url = this.getLoadUrl(); me.loaded = true; if ((exception || status === 0) && !_environment.phantom) { me.error = //<debug> ("Failed loading synchronously via XHR: '" + url + "'. It's likely that the file is either being loaded from a " + "different domain or from the local file system where cross " + "origin requests are not allowed for security reasons. Try " + "asynchronous loading instead.") || //</debug> true; me.evaluated = true; } else if ((status >= 200 && status < 300) || status === 304 || _environment.phantom || (status === 0 && content.length > 0) ) { me.content = content; } else { me.error = //<debug> ("Failed loading synchronously via XHR: '" + url + "'. Please verify that the file exists. XHR status code: " + status) || //</debug> true; me.evaluated = true; } },