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; },