在整个require中,主要的方法就两个:require和define,我们先来看require
require
require作为主函数来引入我们的“模块”,require会从自身的的存储中去查找对应的defined模块,如果没有找到,则这时这个模块有可以存在三种状态:loading, enabling, defining
这就是require中要注意的地方,如果模块还没有被加载,那么它的这三种状态出现的时机是:
- loading 文件还没有加载完毕
- enabling 对该模块的依赖进行加载和模块化
- defining 对正在处理的模块进行加载,并运行模块中的callback
require的load方法的主要代码:
req.load = function (context, moduleName, url) {
var config = (context && context.config) || {},
node;
if (isBrowser) {
//create a async script element
node = req.createNode(config, moduleName, url);
//add Events [onreadystatechange,load,error]
.....
//set url for loading
node.src = url;
//insert script element to head and start load
currentlyAddingScript = node;
if (baseElement) {
head.insertBefore(node, baseElement);
} else {
head.appendChild(node);
}
currentlyAddingScript = null;
return node;
} else if (isWebWorker) {
.........
}
};
req.createNode = function (config, moduleName, url) {
var node = config.xhtml ?
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
return node;
};
node上设定了 async 属性(异步加载script标签),并且在标签上绑定了load等事件,当文件loading完成后,则要做的主要工作是执行 completeLoad 事件函数,但是要注意的是这时候把script加载完成后,立即执行的是script标签内部的内容,执行完后才触发的 completeLoad事件,而在我们的模块里面,一定要用define函数来对模块进行定义,所以这里我们先穿插着来讲讲define干了什么