requirejs源码分析: requirejs 方法–2. context.require(deps, callback, errback);
上一篇 requirejs源码分析: requirejs 方法–1. 主入口 中的return context.require(deps, callback, errback); 调用的是makeRequire方法中的localRequire
function localRequire(deps, callback, errback) {
var id, map, requireMod;if (options.enableBuildCallback && callback && isFunction(callback)) {
callback.__requireJsBuild = true;
}if (typeof deps === 'string') {
if (isFunction(callback)) {
//Invalid call
return onError(makeError('requireargs', 'Invalid require call'), errback);
}//If require|exports|module are requested, get the
//value for them from the special handlers. Caveat:
//this only works while module is being defined.
if (relMap && hasProp(handlers, deps)) {
return handlers[deps](registry[relMap.id]);
}//Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that.
if (req.get) {
return req.get(context, deps, relMap, localRequire);
}//Normalize module name, if it contains . or ..
map = makeModuleMap(deps, relMap, false, true);
id = map.id;if (!hasProp(defined, id)) {
return onError(makeError('notloaded', 'Module name "' +
id +
'" has not been loaded yet for context: ' +
contextName +
(relMap ? '' : '. Use require([])')));
}
return defined[id];
}//Grab defines waiting in the global queue.
intakeDefines();//Mark all the dependencies as needing to be loaded.
context.nextTick(function () {
//Some defines could have been added since the
//require call, collect them.
intakeDefines();
//实例化Module对象
requireMod = getModule(makeModuleMap(null, relMap));//Store if map config should be applied to this require
//call for dependencies.
requireMod.skipMap = options.skipMap;//初始化 Module 对象
requireMod.init(deps, callback, errback, {
enabled: true
});checkLoaded();
});return localRequire;
}
这里主要是方法:
context.nextTick(function () {
//Some defines could have been added since the
//require call, collect them.
intakeDefines();
//实例化Module对象
requireMod = getModule(makeModuleMap(null, relMap));//Store if map config should be applied to this require
//call for dependencies.
requireMod.skipMap = options.skipMap;//初始化 Module 对象
requireMod.init(deps, callback, errback, {
enabled: true
});checkLoaded();
});
这里使用context.nextTick是延迟4ms再执行(异步)。 这里不能很理解作者的目的。 是为了不卡主线程?
该方法主要流程:
1. 实例化Module。
requireMod = getModule(makeModuleMap(null, relMap));
Module也是上下文newContext里的对象。这个是核心模块。包含以下主要的属性。
this.events = getOwn(undefEvents, map.id) || {};
this.map = map;
this.shim = getOwn(config.shim, map.id);
this.depExports = [];
this.depMaps = [];
this.depMatched = [];
this.pluginMaps = {};
this.depCount = 0;
该对象是封装模块,存在模块信息(shim,依赖等。)。 还包含对模块的加载,依赖加载,通知依赖等。