// _load()方法主要会先判断哪些资源文件还没有ready,如果全部资源文件都处于ready状态就执行callback2
// 在这其中还会做循环依赖的判断,以及对没有加载的js执行加载
Module.prototype._load = function(uris, callback2) {
//util.filter : 让数据成员全部执行一次一个指定的函数,并返回一个新的数组,该数组为原数组成员执行回调后返回为true的成员
//unLoadedUris是那些没有被编译的模块uri数组
var unLoadedUris = util.filter(uris, function(uri) {
//返回执行函数布尔值为true的成员,在uri存在并且在内部变量cacheModules中不存在或者它在存储信息中status的值小于STATUS.READY时返回true
// STATUS.READY值为4,小于四则可能的情况是获取中,下载中。
return uri && (!cachedModules[uri] ||
cachedModules[uri].status < STATUS.READY)
});
//如果uris中的模块全部都ready好了,执行回调并退出函数体(这时就会调用模块的_compile方法了)。
var length = unLoadedUris.length
if (length === 0) { callback2() return }
//还未加载的模块个数
var remain = length
//创建闭包,尝试去加载那些没有加载的模块
for (var i = 0; i < length; i++) {
(function(uri) {
//判断如果在内部变量cachedModules里面并不存在该uri的存储信息则实例化一个Module对象
var module = cachedModules[uri] ||
(cachedModules[uri] = new Module(uri, STATUS.FETCHING))
//如果模块的状态值大于等于2,也就意味着模块已经被下载好并已经存在于本地了,这个时候执行onFetched()
//否则则调用fetch(uri, onFetched) ,尝试下载资源文件,资源文件下载后会触发onload,onload中会执行回调onFetched的方法。
module.status >= STATUS.FETCHED ? onFetched() : fetch(uri, onFetched)
function onFetched() {
module = cachedModules[uri]
//当模块的状态值为大于等于STATUS.SAVED的时候,也就意味着该模块所有的依赖信息已经被拿到
if (module.status >= STATUS.SAVED) {
//getPureDependencies:得到不存在循环依赖的依赖数组
var deps = getPureDependencies(module)
//如果依赖数组不为空
if (deps.length) {
//再次执行_load()方法,直到全部依赖加载完成后执行回调
Module.prototype._load(deps, function() {
cb(module)
})
}
//如果依赖数组为空的情况下,直接执行cb(module)
else {
cb(module)
}
}
// 如果获取失败后,比如404或者不符合模块化规范
//在这种情形下,module.status会维持在 FETCHING 或者 FETCHED
else {
cb()
}
}
})(unLoadedUris[i])
}
// cb 方法 - 加载完所有模块执行回调
function cb(module) {
// 如果module的存储信息存在,那么修改它的module存储信息中的status的值,修改为 STATUS.READY
module && (module.status = STATUS.READY)
// 只有当所有模块加载完毕后执行回调。
--remain === 0 && callback2()
}
}
}
javascript框架设计读书笔记之模块加载系统(2)
内容版权声明:除非注明,否则皆为本站原创文章。