• 不要温柔地走入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>
  • 相关阅读:
    一个很大的数(计数、思维)
    第3章 图嵌入
    第一章 绪论
    区间最大值(数论分块)
    爬塔(set、括号匹配)
    第2章 图论基础
    V字钩爪(贪心)
    金牌厨师(二分、差分)
    Coprime(埃氏筛)
    Reordering(组合计数)
  • 原文地址:https://www.cnblogs.com/samwu/p/4542403.html
Copyright © 2020-2023  润新知