不要温柔地走入AMD
1.无依赖情况
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>一步步走入AMD</title>
<script> var req = {};
/*无依赖*/
req.config = {
"a":{
deps:[],
fn:function(){
console.log("a");
}
},
"b":{
deps:[],
fn:function(){
console.log("b");
}
},
"c":{
deps:[],
fn:function(){
console.log("c");
}
},
}
var require = function(deps,fn){
var config = req.config,
deps_arr = []; // 1.找依赖,生成依赖数组
for(var i=0,l = deps.length; i<l; i++){
var deps_item = deps[i];
deps_arr.push(config[deps_item].fn);
} // 2.依赖数组,是入口函数的参数
fn.apply(window,deps_arr);
}; require(["a","b"],function(a,b){
a();
b();
});
</script>
</head>
<body> </body>
</html>
2.有依赖
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>不要温柔地走入AMD</title>
<script>
var req = {};
/*有依赖*/
req.config = {
"a":{
deps:["b"],
fn:function(b){
return function(){
console.log("a");
b();
} }
},
"b":{
deps:["c"],
fn:function(c){
return function(){
console.log("b");
c();
} }
},
"c":{
deps:[],
fn:function(){
var private_c = "cc"
return function(){
console.log("c");
console.log(private_c);
} }
}
}
var require = function(deps,fn){
var config = req.config,
deps_arr = []; var excute_obj = {},
deps_chain = []; for(var i in config){
deps_chain.push(i);
} // 包装各个依赖函数
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
item_fn = function(){
return item["fn"].apply(window,excute_obj[configName]["deps"])();
};
excute_obj[configName] = {};
excute_obj[configName]["fn"] = item_fn; }); // 依赖函数的执行参数生成
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
param_arr = []; item_deps.forEach(function(i){
param_arr.push(excute_obj[i]["fn"]);
}); excute_obj[configName]["deps"] = param_arr; }); console.log(excute_obj); deps.forEach(function(configName){
deps_arr.push(excute_obj[configName]["fn"]);
}); fn.apply(window,deps_arr);
}; // bug:依赖设置错误
require(["a"],function(a){
a(); });
</script>
</head>
<body> </body>
</html>
3.循环依赖判断
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>不要温柔地走入AMD</title>
<script>
var req = {};
/*有循环依赖*/
req.config = {
"a":{
deps:["b","c"],
fn:function(b,c){
return function(){
console.log("a");
b();
c();
} }
},
"b":{
deps:["c"],
fn:function(c){
return function(){
console.log("b");
c();
} }
},
"c":{
deps:["a"],
fn:function(){
return function(){
console.log("c");
} }
}
}
var require = function(deps,fn){
var config = req.config,
deps_arr = []; var excute_obj = {},
deps_chain = []; for(var i in config){
deps_chain.push(i);
}
console.log(deps_chain); function arrayClone(arr){
var _array = [];
for(var i=0,l=arr.length; i<l; i++){
_array.push(arr[i]);
} return _array;
}
function loopDepJudge(currentKey,currentDeps, circleArr){
var check_arr = [];
check_arr.unshift(arrayClone(currentDeps) ); var keyChain = [currentKey];
// 开始循环
(function(){
var currentDeps = check_arr[0];
// console.log(currentDeps);
if(currentDeps.length > 0){
var nextKey = currentDeps.shift(),
nextDeps = circleArr[nextKey];
if(keyChain.indexOf(nextKey) > -1){
keyChain = [false,nextKey,keyChain.pop()];
return;
}
else{
keyChain.push(nextKey);
} if(nextDeps.length > 0){
check_arr.unshift(arrayClone(nextDeps));
}
else{
check_arr.shift();
keyChain = [currentKey];
if(check_arr.length == 0){
return;
}
}
}
else{
return;
}
arguments.callee();
})();
return keyChain;
} (function(){
// 循环依赖检测
var circle_deps = {};
deps_chain.forEach(function(configName){
circle_deps[configName] = config[configName]["deps"];
}); deps_chain.forEach(function(configName){
var key = configName,
deps = arrayClone(circle_deps[key]); var keyChain = loopDepJudge(key,deps,circle_deps);
if(keyChain[0] == false){
throw new Error("有循环依赖。他们是"+keyChain[1]+"和" +keyChain[2]);
}
else{
console.log(keyChain)
}
});
// var keyChain = loopDepJudge() // 包装各个依赖函数
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
item_fn = function(){
return item["fn"].apply(window,excute_obj[configName]["deps"])();
}; excute_obj[configName] = {};
excute_obj[configName]["fn"] = item_fn; }); // 依赖函数的执行参数生成
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
param_arr = []; item_deps.forEach(function(i){
param_arr.push(excute_obj[i]["fn"]);
}); excute_obj[configName]["deps"] = param_arr; }); console.log(excute_obj); })(); deps.forEach(function(configName){
deps_arr.push(excute_obj[configName]["fn"]);
}); fn.apply(window,deps_arr);
}; require(["a"],function(a){
a(); });
</script>
</head>
<body> </body>
</html>
4.define函数定义
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>不要温柔地走入AMD</title>
<script>
var req = {};
/*define函数定义*/
req.requireConfig = {}; var define = function(deps,fn){
var protocal = location.protocal,
host = location.host,
port = location.port,
pathName = location.pathname,
href = location.href, paths = req.userConfig.paths,
baseUrl = req.userConfig.baseUrl || ""; function baseUrlParse(baseUrl){
var str_length = baseUrl.length,
newBaseUrl = "";
if(baseUrl.lastIndexOf("/") == str_length -1){ }
else{
newBaseUrl = baseUrl + "/";
}
return newBaseUrl;
} // 不支持IE
// 1.获取当前js文件地址
var scriptSrc = document.currentScript.src; for (var i in paths) {
var path = paths[i],
complete_path = ""; // 2. 生成complete_path var backslash_pos = href.lastIndexOf("/"),
slash_href = href.substring(0,backslash_pos+1),
complete_path = slash_href + baseUrlParse(baseUrl) + path; // 3. 根据文件地址进行匹配,从而生成req.requireConfig
if(scriptSrc == complete_path){
req.requireConfig[i] = {
"deps":deps,
"fn":fn
};
}
};
};
var require = function(deps,fn){
function arrayClone(arr){
var _array = [];
for(var i=0,l=arr.length; i<l; i++){
_array.push(arr[i]);
} return _array;
}
function loopDepJudge(currentKey,currentDeps, circleArr){
var check_arr = [];
check_arr.unshift(arrayClone(currentDeps) ); var keyChain = [currentKey];
// 开始循环
(function(){
var currentDeps = check_arr[0];
// console.log(currentDeps);
if(currentDeps.length > 0){
var nextKey = currentDeps.shift(),
nextDeps = circleArr[nextKey];
if(keyChain.indexOf(nextKey) > -1){
keyChain = [false,nextKey,keyChain.pop()];
return;
}
else{
keyChain.push(nextKey);
} if(nextDeps.length > 0){
check_arr.unshift(arrayClone(nextDeps));
}
else{
check_arr.shift();
keyChain = [currentKey];
if(check_arr.length == 0){
return;
}
}
}
else{
return;
}
arguments.callee();
})();
return keyChain;
} var config = req.requireConfig,
deps_arr = [],
excute_obj = {},
deps_chain = []; for(var i in config){
deps_chain.push(i);
} // 循环依赖检测
(function(){
var circle_deps = {};
deps_chain.forEach(function(configName){
circle_deps[configName] = config[configName]["deps"];
}); deps_chain.forEach(function(configName){
var key = configName,
deps = arrayClone(circle_deps[key]); var keyChain = loopDepJudge(key,deps,circle_deps);
if(keyChain[0] == false){
throw new Error("有循环依赖。他们是"+keyChain[1]+"和" +keyChain[2]);
}
else{
console.log(keyChain)
}
});
})();// 包装各个依赖函数
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
item_fn = function(){
return item["fn"].apply(window,excute_obj[configName]["deps"])();
};
excute_obj[configName] = {};
excute_obj[configName]["fn"] = item_fn; }); // 依赖函数的参数数组生成
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
param_arr = []; item_deps.forEach(function(i){
param_arr.push(excute_obj[i]["fn"]);
}); excute_obj[configName]["deps"] = param_arr; }); // 主函数的参数数组生成
deps.forEach(function(configName){
deps_arr.push(excute_obj[configName]["fn"]);
}); fn.apply(window,deps_arr);
}; req.userConfig = {
"baseUrl":"",
"paths":{
"a":"a.js",
"b":"b.js",
"c":"c.js"
}
};
</script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="c.js"></script>
<script>
require(["a"],function(a){
a();
});
</script>
</head>
<body> </body>
</html>
5.js加载器生成
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>不要温柔地走入AMD</title>
<script>
/*
1.暂不支持shim
*/
var req = {}; req.requireConfig = {};
req.userConfig= {};
// 用来记录js加载的数目
req.jsLoadCount = 0; function baseUrlParse(baseUrl){
var str_length = baseUrl.length,
newBaseUrl = "";
if(baseUrl.lastIndexOf("/") == str_length -1){ }
else{
newBaseUrl = baseUrl + "/";
}
return newBaseUrl;
} function getObjSize(obj){
var size = 0;
for(var i in obj){
var item = obj[i];
if(item !== null && typeof(item) !== "undefined"){
size++;
}
} return size;
} var define = function(deps,fn){
var protocal = location.protocal,
host = location.host,
port = location.port,
pathName = location.pathname,
href = location.href, paths = req.userConfig.paths,
baseUrl = req.userConfig.baseUrl || ""; // 不支持IE
// 1.获取当前js文件地址
var scriptSrc = document.currentScript.src; for (var i in paths) {
var path = paths[i],
complete_path = ""; // 2. 生成complete_path
var backslash_pos = href.lastIndexOf("/"),
slash_href = href.substring(0,backslash_pos+1),
complete_path = slash_href + baseUrlParse(baseUrl) + path; // 3. 根据文件地址进行匹配,从而生成req.requireConfig
if(scriptSrc == complete_path){
req.requireConfig[i] = {
"deps":deps,
"fn":fn
};
}
};
};
var require = function(deps,fn){
// 检测js加载完毕与否
var timer_loader = setTimeout(function(){
if(req.jsLoadCount == 0){
clearTimeout(timer_loader);
mainRequire();
}
else{
timer_loader();
}
},200); function mainRequire(){
function arrayClone(arr){
var _array = [];
for(var i=0,l=arr.length; i<l; i++){
_array.push(arr[i]);
} return _array;
}
function loopDepJudge(currentKey,currentDeps, circleArr){
var check_arr = [];
check_arr.unshift(arrayClone(currentDeps) ); var keyChain = [currentKey];
// 开始循环
(function(){
var currentDeps = check_arr[0];
// console.log(currentDeps);
if(currentDeps.length > 0){
var nextKey = currentDeps.shift(),
nextDeps = circleArr[nextKey];
if(keyChain.indexOf(nextKey) > -1){
keyChain = [false,nextKey,keyChain];
return;
}
else{
keyChain.push(nextKey);
} if(nextDeps.length > 0){
check_arr.unshift(arrayClone(nextDeps));
}
else{
check_arr.shift();
keyChain = [currentKey];
if(check_arr.length == 0){
return;
}
}
}
else{
return;
}
arguments.callee();
})();
return keyChain;
}
var config = req.requireConfig,
deps_arr = [],
excute_obj = {},
deps_chain = []; for(var i in config){
deps_chain.push(i);
}
console.log(config); // 循环依赖检测
(function(){
var circle_deps = {};
deps_chain.forEach(function(configName){
circle_deps[configName] = config[configName]["deps"];
});
console.log(circle_deps); deps_chain.forEach(function(configName){
var key = configName,
deps = arrayClone(circle_deps[key]); var keyChain = loopDepJudge(key,deps,circle_deps);
if(keyChain[0] == false){
throw new Error("前方高能,有循环依赖。他们是"+keyChain[1]+"和" +keyChain[2]);
}
else{
console.log(keyChain)
}
});
})(); // 包装各个依赖函数
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
item_fn = function(){
return item["fn"].apply(window,excute_obj[configName]["deps"])();
};
excute_obj[configName] = {};
excute_obj[configName]["fn"] = item_fn; }); // 依赖函数的参数数组生成
deps_chain.forEach(function(configName){
var item = config[configName],
item_deps = item["deps"],
param_arr = []; item_deps.forEach(function(i){
param_arr.push(excute_obj[i]["fn"]);
}); excute_obj[configName]["deps"] = param_arr; }); // 主函数的参数数组生成
deps.forEach(function(configName){
deps_arr.push(excute_obj[configName]["fn"]);
}); fn.apply(window,deps_arr);
}
};
require.config = function(config_obj){
req.userConfig = config_obj;
req.jsLoadCount = getObjSize(config_obj.paths); function generateScript(url,loadCount){
var _script = document.createElement('script');
_script.type = 'text/javascript';
_script.charset = 'utf-8';
_script.async = true;
_script.src = url;
_script.onload = function(){
req.jsLoadCount--;
};
_script.onerror = function(e){
throw new Error(e);
}; var fs = document.getElementsByTagName('script')[0];
fs.parentNode.insertBefore(_script, fs);
}
var href = location.href,
baseUrl = req.userConfig.baseUrl || "";
paths = req.userConfig.paths;
for(var i in paths){
var path = paths[i],
backslash_pos = href.lastIndexOf("/"),
slash_href = href.substring(0,backslash_pos+1),
complete_path = slash_href + baseUrlParse(baseUrl) + path;
generateScript(complete_path);
} } require.config({
"baseUrl":"",
"paths":{
"c":"c.js?v=3",
"a":"a.js",
"b":"b.js"
}
}); require(["a","b"],function(a,b){
a();
b();
}); </script> </head>
<body> </body>
</html>
不要温柔地走入AMD的更多相关文章
- 不要温柔地走入promise
第一步 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title ...
- AngularJs2与AMD加载器(dojo requirejs)集成
现在是西太平洋时间凌晨,这个问题我鼓捣了一天,都没时间学英语了,英语太差,相信第二天我也看不懂了,直接看结果就行. 核心原理就是require在AngularJs2编译过程中是关键字,而在浏览器里面运 ...
- js模块定义——支持CMD&AMD&直接加载
/* animate */ //直接加载 (function() { var animate = {} //balabala window.animate = animate; })(); //AMD ...
- JavaSript模块规范 - AMD规范与CMD规范介绍
JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发? 模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题 ...
- AMD电脑装完Winsows10后开机蓝屏,报错代码:cdmsnroot_s.sys
背景:今天装了个WIN10,电脑配置:联想 IdeaPad Z485 : AMD A8处理器 .完成安装后电脑没有问题,安装了驱动程序后将 电脑用360 ...
- JavaScript的模块化之AMD&CMD规范
前端开发常常会遇到的问题: 1.恼人的命名冲突: 2.繁琐的文件依赖: 模块化开发的优势: 1.解决命名冲突和依赖管理: 2.模块的版本管理: 3.提高代码的可维护性: 4.前端性能优化: JavaS ...
- Javascript模块化编程(二):AMD规范
Javascript模块化编程(二):AMD规范 作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_d ...
- CommonJS, AMD 和 RequireJS之间的关系(转载)
先说说CommonJS CommonJS - 大家是不是觉得JavaScript仅仅是一个客户端的编译语言,其实JavaScript设计之初不仅仅是针对客户端设计的语言.后来只是由于Web的迅速流行, ...
- Can't load IA 32-bit .dll on a AMD 64-bit platform错误的解决
64位的系统,64位的myeclipse,64位的jdk,64位的tomcat,结果报错:Can't load IA 64-bit .dll on a AMD 32-bit platform,简直无语 ...
随机推荐
- Mac OX 隐藏文件夹,文件,应用,磁盘的2种方法 hide finder folder, file, application, volume in 2 ways
经常需要主目录下隐藏一些文件夹之类的, 第一想到的当然就是:在要隐藏的文件夹前面加『.』(leading dot),这个用法当然可以的了 用习惯了Linux/GNU系统的,基本习惯使用这种办法 但是, ...
- tomcat缓存静态资源深入
之前看过apach及nginx对于静态资源(含js,图片,css等)部分的缓存,用于加速并减轻后台实际web服务器的压力. 静态资源缓存是WEB服务器优化的一种手段,基本原理如下: 1.客户端浏览器请 ...
- Apache httpd和JBoss构建高可用集群环境
1. 前言 集群是指把不同的服务器集中在一起,组成一个服务器集合,这个集合给客户端提供一个虚拟的平台,使客户端在不知道服务器集合结构的情况下对这一服务器集合进行部署应用.获取服务等操作.集群是企业应用 ...
- WordPress博客系统搜索引擎优化seo全攻略方法
WordPress的文章.评论等很多数据都是存放在数据库的,所以搭建wordpress网站的时间,网站的空间不需要多大,而数据库一定要充足,而在WordPress数据库中主要使用 wp_posts 表 ...
- PHP serialize & JSON 解析
对于JSON(JavaScript Object Notation)大家应该不陌生,它是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Program ...
- javaBean的使用方法;
在jsp页面中使用javaBean:三个标签: <jsp:useBean>标签 <jsp:setProperty>标签 <jsp:getProperty>标签 首先 ...
- Oracle插入时间
现象:Oracle 插入时间时 ,报错:ORA-01861: 文字与格式字符串不匹配 解决方法: 这个错误一般出现在时间字段上,即你插入的时间格式和数据库现有的时间格式不一致,解决的方法是格式化你 插 ...
- libevent安装及使用
一.安装libevent 官网:http://libevent.org/ 选择最新版本下载,我选择的是libevent-2.0.22-stable.tar.gz,然后安装README文件中描述的方法编 ...
- HTTP断点续传的基本原理
转自:http://blog.csdn.net/sendy888/article/details/1719105 断点续传是我们现在经常接触的概念,那么HTTP协议是如何支持断点续传的呢.我们先从一个 ...
- android 入门 001 (界面布局)
学android 首先学会怎么布局界面,我开始是学.net的,因工作需要学习一下安卓,外行写的不好,请多多见谅指教 .这一篇文章然我们来学习一下四种布局吧! RelativeLayout(相对布局) ...