1. 问题描述:
Ext文件异步加载、解释、执行的问题。因为这里涉及了EXT面向对象,所以需要对EXT类的定义有深入的理解(本文略)。
2. 一个简单的异步加载思路
/** * 定义需要加载的模块的文件路径 */ loadUserModule = function (callback) { var js = ["/paims/users/User.js"]; js[js.length] = "/paims/users/UserStore.js"; js[js.length] = "/paims/users/UserXmlReader.js"; js[js.length] = "/paims/users/UserGridPanel.js"; js[js.length] = "/paims/users/UserGridPanel_ColumnModel.js"; loadJs(js, ‘用户模块‘, function () { // 调用异步加载方法,加载文件 callback(); }); }
/** * 异步加载JS文件 */ loadJs = function (jsPath,moduleName,callback) { if (Ext.type(js) != ‘string‘) { if (js.length == 1) { js = js[0]; } else { js = js.shift(); callback = loadJs; } } Ext.Ajax.request({ url: ‘/javascript‘ + js, success: onLoadJs, method: ‘GET‘, scope: callback }); }
/** * 文件加载完成之后,解释执行 */ onLoadJs = function (response) { eval(response.responseText); // 解释执行JS文件内容,忽略eval的副作用 this(); // 执行回调 }
3. 运行效果如下:
异步加载方法,会逐个的去加载模块中JS文件,每成功加载一个文件,就立即解释执行,然后再去加载下一个文件。
4.UserStore和UserXmlReader两个文件的内容如下:
Paims.users.UserStore = Ext.extend(Paims.data.XmlStore, { constructor: function(load_url, params){ Paims.users.UserStore.superclass.constructor.call(this, new Paims.users.UserXmlReader(), load_url, params); } });
Paims.users.UserXmlReader = Ext.extend(Paims.data.XmlReader, { constructor: function(){ Paims.users.UserXmlReader.superclass.constructor.call(this, Paims.users.User); } });
观察UserStore的源码可以发现,在UserStore中用到了UserXmlReader类。第一直觉,会认为这里在解释执行UserStore文件的时候会报异常。事实上,却一切正常。因为,依赖关系写到了constructor方法里,而方法没有被解释执行。
5.深入体会Ext类的定义和执行
修改UserStore类的定义如下:
Paims.users.UserStore = Ext.extend(Paims.data.XmlStore, { constructor: function(load_url, params){ Paims.users.UserStore.superclass.constructor.call(this, new ABC(), load_url, params); } });
UserStore中依赖了一个毫无相关的ABC类(方法)。
加载UserStore文件,并解释执行,一切正常,如下图:
只有当UserStore被实例化,执行constructor方法的时候,才会报错,如下图:
这里可以这样理解,在加载文件并解释执行的时候,只是解释执行了最外层方法的内容。如果没有显示的执行调用的话,内层的方法是不会执行了。
比如,上例中解释执行的时候,只是执行了最外层的Ext.extend()方法,内层的constructor方法并不会被解释执行,所以new ABC()语句也不会被解释执行。
6. 对于解释执行的理解:
修改UserStore类的定义如下:
Paims.users.UserStore = Ext.extend(Paims.data.XmlStore, { constructor: function(load_url, params){ Paims.users.UserStore.superclass.constructor.call(this, new ABC(), load_url, params); } }); new ABC(); // 注意
这次,当解释执行UserStore文件的时候会报错,如下图:
7. 两个小例子
解释执行最外层
执行内层方法name()
解释执行最外层
执行方法fn()
总结:虽然JS是边解释边执行,但是没有被显示调用的方法只会被解释,不会被执行,只会被检查编译时错误(语法),不会被检查运行时错误。
本文出自 “技术人生” 博客,请务必保留此出处http://wangyuelucky.blog.51cto.com/1011508/1562445
原文地址:http://wangyuelucky.blog.51cto.com/1011508/1562445