对比requirejs更好的理解seajs
seajs遵循CMD规范,requirejs遵循AMD规范。AMD规范是预加载,CMD规范是赖加载。
下文举例假设有文件 b.js, c.js如下
//b.js
define(function(require, exports, module){
console.log('b is loaded')
function run(){
console.log('b run');
}
exports.run = run;
})
//c.js
define(function(require, exports, module){
console.log('c is loaded')
function run(){
console.log('c run');
}
exports.run = run;
})
1. seajs对依赖模块只加载不执行,requirejs对依赖模块既加载也执行
运行代码:
// seajs
<!DOCTYPE html>
<html>
<head>
<title>seajs</title>
<script type="text/javascript" src="./sea.min.js"></script>
</head>
<body>
<button id="btn">OK</button>
<script type="text/javascript">
seajs.use('./a.js')
</script>
</body>
</html>
// requirejs
<!DOCTYPE html>
<html>
<head>
<title>requirejs</title>
<script type="text/javascript" src="./require.js"></script>
</head>
<body>
<button id="btn">OK</button>
<script type="text/javascript">
require(['a'])
</script>
</body>
</html>
// a.js
define(['b'], function(){
})
运行结果:
seajs:
控制台无输出
requirejs:
控制台:
2. seajs ,requirejs在 require文件时既加载也执行
//a.js
define(function(require, exports, module){
var b = require('b')
})
requirejs:
控制台:b is loaded
seajs:
控制台:b is loaded
3. seajs可以在任意处直接require文件,无需提前写依赖模块;一旦提前写了任意一个依赖模块,下面的所有require的使用必须保证也有其对应的依赖模块
seajs可以直接如下使用,无需写依赖['b']:
//a.js
define(function(require, exports, module){
var b = require('b')
})
或
运行结果:
控制台:b is loaded
假如 a.js 依赖了另一个 c.js,则在 a.js 中使用 require('b') 时必须也写上依赖['b'],否则b.js将因为查找不到而不会加载
define(['c'], function(require, exports, module){
var b = require('b')
})
运行结果:
控制台无输出(不会输出c is loaded, 因为没有require('c') )
如果此时我们执行b.run()
define(['c'], function(require, exports, module){
var b = require('b')
b.run()
})
控制台将会报错,因为此时b为null:
此时正确写法应该写上依赖 ['b']:
define(['c', 'b'], function(require, exports, module){
var b = require('b')
b.run()
})
运行结果:
结论:
对于seajs,如果不写依赖那就一个都不要写,一旦写了,下面所有require的地方都需要提前在头部写上依赖
requirejs的依赖写法如下:
define(['c', 'b'], function(c, b){
var b = require('b')
b.run()
})
或
define(function(require, exports, module){
var b = require('b')
b.run()
})
//错误写法
define(['c'], function(c){
var b = require('b')
b.run()
})
4. seajs的require.async在执行到使用位置的时候才去异步加载
seajs:
如下例:
// a.js
define(function(require, exports, module){
document.getElementById('btn').addEventListener('click', function(){
document.getElementById('btn').innerHTML = 'btn is clicked'
init()
})
function init(){
var b = require('b');
b.run()
}
})
运行结果:
控制台无输出
点击OK按钮, b.js 加载并执行b.js和run方法:
大家注意到,在未点击按钮之前,虽然没有执行init方法,但b.js依然被提前加载了进来,但没有被执行(没有输出b is loaded)。
很多时候我们想在执行init方法的时候再去加载b.js,而不是提前在页面加载的时候就把b,js加载。
这时候就需要用到require.async,如下:
//a.js
define(function(require, exports, module){
document.getElementById('btn').addEventListener('click', function(){
document.getElementById('btn').innerHTML = 'btn is clicked'
init()
})
function init(){
require.async('b', function(b){
b.run()
});
}
})
这时候运行结果:
b.js没有被加载:
控制台无输出:
点击OK按钮:
b.js被加载
控制台输出:
这是因为当执行一个js时,seajs会先去查找匹配require,然后加载相应资源,但不执行。匹配到require.async时不加载。
所以,require.async达到了用到时再去异步加载并执行的目的。
小问题:
如果是requirejs执行下面代码:
//a.js
define(function(require, exports, module){
document.getElementById('btn').addEventListener('click', function(){
document.getElementById('btn').innerHTML = 'btn is clicked'
init()
})
function init(){
var b = require('b');
b.run()
}
})
资源如何加载?控制台又会输出什么呢?点击ok按钮又会输出啥? 答:资源加载了a.js, b.js, 控制台输出:b is loaded, 点击OK按钮控制台继续输出:b run (选择“答”后面的部分查看答案)
总结:
1. seajs对依赖模块只加载不执行,requirejs对依赖模块加载并执行
2. seajs ,requirejs在 require具体文件时既加载也执行
3. seajs可以在任意处直接require文件,无需提前写依赖模块;一旦提前写了任意一个依赖模块,下面的所有require的使用必须保证也有其对应的依赖模块
4. seajs的require.async在执行到使用位置的时候才去异步加载
本文demo:
https://github.com/saysmy/seajs-requirejs-demo
- 使用正则表达式求完整路径中的文件名
- “AS3.0高级动画编程”学习:第四章 寻路(AStar/A星/A*)算法 (下)
- Centos下SFTP双机高可用环境部署记录
- as3:Function以及call,apply
- centos6下redis cluster集群部署过程
- centos6下ActiveMQ+Zookeeper消息中间件集群部署记录
- 发布一个轻量级的滑块控件
- as3:sprite作为容器使用时,最好不要指定width,height
- openssl版本升级操作记录
- 清除浮动(clearfix hack)
- Linux下环境变量配置方法梳理(.bash_profile和.bashrc的区别)
- 小程序火爆的因素
- Log4Net使用心得
- nginx通过https方式反向代理多实例tomcat
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java自动化测试(web自动化测试框架2 29)
- 精讲RestTemplate第9篇-如何通过HTTP Basic Auth认证
- 【Rust日报】2020-09-14 测试数据表明, Rust 可以帮你省钱!
- 【43期】盘点那些必问的数据结构算法题之二叉树基础
- 精讲RestTemplate第8篇-请求失败自动重试机制
- 精讲RestTemplate第7篇-自定义请求失败异常处理
- 精讲RestTemplate第10篇-使用代理作为跳板发送请求
- 精讲响应式WebClient第5篇-请求超时设置与异常处理
- 精讲响应式WebClient第4篇-文件上传与下载
- 【大家的项目】Rust Base62 库学习和分析
- ES2020 中 Javascript 10 个你应该知道的新功能
- Webpack5 跨应用代码共享 - Module Federation
- 【Rust日报】2020-09-16 - Rust 2021 规划
- 精讲响应式WebClient第3篇-POST、DELETE、PUT方法使用
- C++的黑魔法: 用四种方式实现add!