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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;
(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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//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的写法吧!想必看了上面的代码就知道这个代码的意思,现在来让我们实现它吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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)
};

  

1
2
<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的基本原理是足够了的,希望对同学们模块化开发有帮助

posted @   兜_兜  阅读(1562)  评论(0编辑  收藏  举报
编辑推荐:
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
阅读排行:
· Sdcb Chats 技术博客:数据库 ID 选型的曲折之路 - 从 Guid 到自增 ID,再到
· 语音处理 开源项目 EchoSharp
· 《HelloGitHub》第 106 期
· mysql8.0无备份通过idb文件恢复数据过程、idb文件修复和tablespace id不一致处
· 使用 Dify + LLM 构建精确任务处理应用
点击右上角即可分享
微信分享提示