这里是seajs loader的核心部分,有些IE兼容的部分还不是很明白,主要是理解各个模块如何依赖有序加载,以及CMD规范。
代码有点长,需要耐心看:
代码如下:
/**
* The core of loader
*/
;(function(seajs, util, config) {
// 模块缓存
var cachedModules = {}
// 接口修改缓存
var cachedModifiers = {}
// 编译队列
var compileStack = []
// 模块状态
var STATUS = {
'FETCHING': 1, // The module file is fetching now. 模块正在下载中
'FETCHED': 2, // The module file has been fetched. 模块已下载
'SAVED': 3, // The module info has been saved. 模块信息已保存
'READY': 4, // All dependencies and self are ready to compile. 模块的依赖项都已下载,等待编译
'COMPILING': 5, // The module is in compiling now. 模块正在编译中
'COMPILED': 6 // The module is compiled and module.exports is available. 模块已编译
}
function Module(uri, status) {
this.uri = uri
this.status = status || 0
// this.id is set when saving
// this.dependencies is set when saving
// this.factory is set when saving
// this.exports is set when compiling
// this.parent is set when compiling
// this.require is set when compiling
}
Module.prototype._use = function(ids, callback) {
//转换为数组,统一操作
util.isString(ids) && (ids = [ids])
// 使用模块系统内部的路径解析机制来解析并返回模块路径
var uris = resolve(ids, this.uri)
this._load(uris, function() {
// Loads preload files introduced in modules before compiling.
// 在编译之前,再次调用preload预加载模块
// 因为在代码执行期间,随时可以调用seajs.config配置预加载模块
preload(function() {
// 编译每个模块,并将各个模块的exports作为参数传递给回调函数
var args = util.map(uris, function(uri) {
return uri ? cachedModules[uri]._compile() : null
})
if (callback) {
// null使回调函数中this指针为window
callback.apply(null, args)
}
})
})
}
// 主模块加载依赖模块(称之为子模块),并执行回调函数
Module.prototype._load = function(uris, callback) {
// 过滤uris数组
// 情况一:缓存中不存在该模块,返回其uri
// 情况二:缓存中存在该模块,但是其status < STATUS.READY(即还没准备好编译)
var unLoadedUris = util.filter(uris, function(uri) {
return uri && (!cachedModules[uri] ||
cachedModules[uri].status < STATUS.READY)
})
var length = unLoadedUris.length
// 如果length为0,表示依赖项为0或者都已下载完成,那么执行回调编译操作
if (length === 0) {
callback()
return
}
var remain = length
for (var i = 0; i < length; i++) {
// 闭包,为onFetched函数提供上下文环境
(function(uri) {
// 创建模块对象
新闻热点
疑难解答
图片精选