1、加载机制
require(['sample'],function(sample){
// some codes
});
首先是解析依赖模块,deps.shift(); 为每一个依赖模块创建script标签
其次是异步加载script文件,加载过程中首先运行script define外脚本,然后执行define的流程机制
接着 var data = getScriptData(evt);返回的 data.id 其实就是依赖模块的 name
然后 执行contex.completeLoad(node.id),把define中注册的name和这里得到的name进行比较如果相等就执行
直到所有的依赖模块加载完成(如果超时也算执行完成),然后执行回调函数,并且把依赖模块的返回值作为参数传入回调函数
2、注意是异步加载
require(['sample2','sample3','sample4'],function(sample){
// some codes
});
虽然创建script标签是按照数组的顺序,但是由于script是异步加载的,所以到底谁先运行是不确定的!
所以,如果你在sample4的define里面通过require('sample3')是不一定有效的!同理,在sample3的define中require('sample4')也是不一定有效的!想要这样调用必须在define的定义模块中显示声明依赖的模块!
另外,如果在require回调方法内部当然是可以如上调用,因为回调函数是保证所有依赖加载都完成时才会被调用!那么只要保证模块已经被加载在系统当中,就可以在require回调函数内部使用require('module');这样可以方便调试!
3、函数源代码
// 新的版本中,通过 require = req
req = requirejs = function (deps, callback, errback, optional) {
//Find the right context, use default
var context, config,
contextName = defContextName;
// Determine if have config object in the call.
if (!isArray(deps) && typeof deps !== 'string') {
// deps is a config object
config = deps;
if (isArray(callback)) {
// Adjust args if there are dependencies
deps = callback;
callback = errback;
errback = optional;
} else {
deps = [];
}
}
if (config && config.context) {
contextName = config.context;
}
context = getOwn(contexts, contextName);
if (!context) {
context = contexts[contextName] = req.s.newContext(contextName);
}
if (config) {
context.configure(config);
}
return context.require(deps, callback, errback);
};
// 老版本中是这样定义的
require: function (deps, callback, relModuleMap) {
var moduleName, fullName, moduleMap;
if (typeof deps === "string") {
if (isFunction(callback)) {
//Invalid call
return req.onError(makeError("requireargs", "Invalid require call"));
}
//Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that.
//In this case deps is the moduleName and callback is
//the relModuleMap
if (req.get) {
return req.get(context, deps, callback);
}
//Just return the module wanted. In this scenario, the
//second arg (if passed) is just the relModuleMap.
moduleName = deps;
relModuleMap = callback;
//Normalize module name, if it contains . or ..
moduleMap = makeModuleMap(moduleName, relModuleMap);
fullName = moduleMap.fullName;
if (!(fullName in defined)) {
return req.onError(makeError("notloaded", "Module name '" +
moduleMap.fullName +
"' has not been loaded yet for context: " +
contextName));
}
return defined[fullName];
}
//Call main but only if there are dependencies or
//a callback to call.
if (deps && deps.length || callback) {
main(null, deps, callback, relModuleMap);
}
//If the require call does not trigger anything new to load,
//then resume the dependency processing.
if (!context.requireWait) {
while (!context.scriptCount && context.paused.length) {
resume();
}
}
return context.require;
},