• javascript设计模式——AMD模式学习


    模块化:将复杂的系统分解为高内聚、低耦合的模块,使系统开发变得可控、可维护、可拓展,提高模块的复用率。
    异步模块——AMD:请求发出后,继续其他业务逻辑,知道模块加载完城执行后续的逻辑,实现模块开发中对模块加载完成后的引用。
    优点有很多,比如:
    1:懒加载,提高网站性能
    2:功能模块化
    3:解决命名冲突
    4:...
    参考require.js,那么我们来实现一个简单的amd库,主要有三个模块方法
    1.config——配置模块路径
    2.define——定义模块方法
    3.require——模块入口方法
    以下是实现学习版的基本函数

    ;
    (function(win) {
        win.config = {}; //路径配置
        var cache = {}, //模块缓存
            require = function(deps, callback) {//模块入口方法,deps,依赖模块
                count = 0, //未加载的模块计数器
            },
            define = function(url, callback) {}, //定义模块方法
            loadModule = function(url, callback) {}, //模块加载方法
            loadDone = function(params, callback){},//所有模块加载完毕
            loadSript = function(url) {}; //加载js文件
        win.require = require;
        win.define = define;
    })(window);
    

      同时我们新建三个js文件,皆为同一个路径,分别为demo.js,demo1.js,demo2.js

    //demo1.js文件内容
    define('demo1',function(){
        return {
            a: 1
        }
    })
    //demo2.js文件内容
    define('demo2',function(){
        return {
            b: 2
        }
    })
    //demo.js
    window.config = {
        demo1: './demo1.js',
        demo2: './demo2.js'
    }
    require(['demo1', 'demo2'], function(demo1, demo2) {
        console.log(demo1)
        console.log(demo2)
    })
    

      上面看起来很像是require.js的写法吧!想必看了上面的代码就知道这个代码的意思,现在来让我们实现它吧!

            require = function(deps, callback) { //模块入口方法
                /*url:需要加载的文件,deps,依赖模块*/
                var i = 0,
                    params = [],
                    count = 0; //未加载的模块计数器
                for (; i < deps.length; i++) {
                    count++;
                    (function(index) { //闭包保存i值
                        loadModule(deps[index], function(module) {
                            count--
                            params[index] = module
                            if (count == 0) {//为0则所有模块加载完毕
                                loadDone(params, callback)
                            }
                        })
                    })(i);
                }
            },
            define = function(url, callback) { //定义模块方法
                cache[url].export = callback() //缓存
                cache[url].onload(cache[url].export) //执行回调
            },
            loadModule = function(url, callback) { //模块加载方法
                if (!cache[url]) { //如果不存在模块则加载并缓存
                    cache[url] = {
                        onload: callback,
                        export: null
                    };
                    loadSript(config[url])
                } else {//否则直接从缓存中输出
                    callback(cache[url].export)
                }
            },
            loadDone = function(params, callback) { //所有模块加载完毕
                callback.apply(null, params)
            },
            loadSript = function(url) { //加载js文件
                var script = document.createElement('script');
                script.async = true;
                script.type = 'text/javascript';
                script.src = url
                script.charset = 'UTF-8';
                document.querySelector('body').appendChild(script)
            };
    

      

        <script src="requireDemo.js"></script>
        <script src="demo.js"></script>
    

      requireDemo.js就是我们写的demo版本的amd的库,运行demo.js,看看log出现什么
      但是以上代码还存在许多问题,如:
      没有处理参数,字符串
      没有处理循环依赖问题
      没有处理CMD写法
      没有处理js文件加载状态
      define一个模块显示的声明id,应该可以忽略显示的声明id,如define(function(){}),有兴趣的同学可以参考司徒的文章getCurrentScript获得当前js执行文件名称
      还有其他许多问题,但是对我们理解amd的基本原理是足够了的,希望对同学们模块化开发有帮助

  • 相关阅读:
    一个java点菜程序
    团队成员
    CentOS tomcat普通用户执行配置安装
    varnish的监控和调试
    组播协议和组播路由
    AVAYA加外线DID,30B+D
    vi技巧
    CentOS开启Telnet服务
    juniper 虚拟路由
    DOS批处理下操作telnet实现自动远程登录操作
  • 原文地址:https://www.cnblogs.com/doudoujs/p/10382443.html
Copyright © 2020-2023  润新知