AMD规范的的RequireJS能不能不写jquery 回调函数 参数里面的参数

requirejs教程
推荐看这txt:
首先要知道为什么要使用requirejs?
1,防止JS阻塞浏览器渲染。例如我们执行alert时,在alert代码之后的html就会停止加载页面的内容就不会在出现了。
2,防止页面加载过多JS相互依赖时,页面出现过多的&script type="text/javascript"&&/script&页面变丑。
这是我们需要requirejs的2大理由,还有其他一些附加功能也方便我们维护JS。
require会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短
define 定义一个模块
require 加载依赖模块,并执行加载完后的回调函数
/********************以下是基本用法********************/
require([],fn) //第一个参数必须是数组放索引0位置的先执行,第二个参数是回调函数也就是第一个参数里面的js加载成功后才执行。
&script type="text/javascript" src="js/require.js"&&/script& //首先加载requirejs
&script type="text/javascript"&
require(["js/a"]); // require就相当于加载器,a其实就是a.js不能加.js
require(["js/a"],function(){ //参数1:加载的js,参数2:参数1的js加载成功后的回调函数
alert("load finished");
定义一个模块a.js 必须用define()
define(function(){
function fun1(){
alert("it works");
加载a.js模块
加载一个模块要用require()
require(["js/a"]);
需要注意:在AMD规范中优先加载依赖模块,也就是依赖前置,例如:
define(function (require, exports, module) {
var a =require('./modulevv');
console.log('a');
var b =require('./moduleuu');
console.log('b');
加载顺序是:1,3,2,4
只要是对外引入了依赖模块,就会优先加载依赖模块
不支持软加载,例如:
if(false){
require('./moduleuu');
//就算是false,也会加载到moduleuu模块
为a.js模块返回一个回调
require(["js/a"],function(){
alert("load finished");
//加载a模块完成后返回一个回调函数
给js文件自定义别名,先加载远程文件如果失败在加载本地文件。paths
在回调的函数中如果依赖jquery就在参数中添加$,如果还有别的依赖还可以添加。
require.config({
"jquery" : ["http://xx/jquery/2.0.3/jquery", "js/jquery"], //别名:['先加载1','备用地址1','备用地址2']
"a" : "js/a"
require(["jquery","a"],function($){
$(function(){
alert("load finished");
我们把require.config的配置加入到data-main后,以后每个页面使用下面的代码就行了
//创建一个 main.js以后这个就是入口了
&script data-main="js/main" src="js/require.js"&&/script&
解决不支持AMD插件的加载问题
shim可以为requirejs加载非AMD规范的其他库
我们用的最多的jquery插件很多都不支持AMD,而我们使用require.js默认是以AMD加载JS的,为了保证jquery插件在jquery.js加载完之后才执行,所以要使用shim
require.config({
"jquery.form" : {
deps : ["jquery"]
//jquery.form依赖jquery,也就是先加载jquery后才能加载jquery.form
exports:["jquery.form"]
//表明这个模块外部调用时的名称
'avalon': {
exports: "avalon" //将avalon对象在requirejs中暴露出来
require(['jquery.form'],function(){
//由于之前设置好了依赖关系可以直接加载jquery.form
//这样默认先加载jquery,后才加载jquery.form
也可以简写为:
// 简写用在avalon上没成功,还是不推荐简写吧
require.config({
"jquery.form" : ["jquery"]
//这个是deps的简写
这样配置之后我们就可以使用加载插件后的jquery了
require.config(["jquery", "jquery.form"], function($){
$(function(){
$("#form").ajaxSubmit({...});
或者我们修改插件让插件支持AMD加载
;(function (factory) {
if (typeof define === "function" && define.amd) {
// AMD模式
define([ "jquery" ], factory);
// 全局模式
factory(jQuery);
}(function ($) {
/*---------我们代码---------------- */
$.fn.extend({
'color':function(value1,value2){
$(this).css({'color':value1,'background':value2});
/*---------我们代码---------------- */
在老版本的jquery中,是没有继承AMD规范的,所以不能直接require["jquery"],这时候就需要shim,比如我要是用underscore类库,但是他并没有实现AMD规范,那我们可以这样配置
require.config({
"underscore" : {
exports : "_";
这样配置后,我们就可以在其他模块中引用underscore模块:
require(["underscore"], function(_){
_.each([1,2,3], alert);
shim中的init在不使用define()模块加载其他js
我们知道要在requirejs中加载js就必须定义在define()模块中,其他的模块才能加载
使用shim中的init就可以不需要,如:
function c(){
alert('11');
function w(){
alert('11');
c:{ //这里指的是c.js
init:function(){
c0:c, //c和w指的是函数体的名称
require(['c'],function(fn){
console.log(fn);
//fn就是返回的对象 {c0:c,c1:w}
baseUrl路径
data-main="js/main" //这里的main.js里面所写的代码将在加载完reuqire.js后处理,这里需要到data-*自定义属性所以IE7以下不支持
如果需要每个页面都要加载到的JS代码就写在main.js即可。
这里注意以下路径问题"js/main"就相当于
require.config({
baseUrl : "js"
也就是说原来需要 "js/a"现在只写成 "a"就行了
版本号更新
//要在加载require.js之前写上
var require = {
urlArgs: "ver=" + (new Date()).getTime()
&script data-main="js/main" src="js/require.js"&&/script&
版本号冲突问题map
//默认其他模块都使用此jq版本号
'jquery': 'jquery-1.10.2.min'
//指定a.js模块使用此版本号
'jquery': 'jquery-1.8.3.min'
requirejs推荐一个JS一个模块,模块变量和方法之间的访问
define([],function(){
//*注意 即使没有要载入的模块默认也要加入空数组[]
//对象里面的变量和方法都是私有的
run:function(){
return this.wo+'-----';
return{ //对外提供接口
wo:obj.wo,
run:obj.run()
hello.js依赖a.js才能获取到数据
define(['a'],function(a){
alert(a.run);
main.js开始加载hello.js
require(['hello']);
让某些模块优先比其他模块先加载
priority:['text','css']
//text.js和css.js模块优先比其他模块先加载
模块对外提供接口
*注意模块的命名不能使用module.js这种关键字名称
当 exports 与 init 同时存在的时候, exports 将被忽略。
define(['jquery'],function($){
function run(){
$(function(){
alert( $().jquery );
//在main.js中调用,
require(["home"],function(home){
home.hello();
哪里都可以调用home.hello();只要加载就行
如果当模块加载失败时候也需要回调处理
require(["mmRouter1","a1"], function(e,a) {
},function(err){
var failedId = err.requireModules && err.requireModules[0];
console.log(failedId)
//输出 错误的模块名称,有多少个模块出错就输出多少个 mmRouter1
requirejs 提供DOM加载 类似jquery
ready()方法
domReady下载和用法:
config所有参数:
其他教程:
← 上一页:
←下一页:育知同创HTML5培训技术分享—模块化开发
育知同创HTML5培训技术分享—模块化开发
育知同创教育
模块化开发概念把JS文件划分开,避免全部冗余在一起为什么需要模块化开发?使文件更加清晰模块之间的可以互相引用html中引入JS更加方便快捷AMD、CMD、CommonJS规范介绍AMD是RequireJS在推广过程中对模块定义的规范化产出
Asynchomous Module Definition(异步模块定义)中文APICMD是Sea.JS在推广过程中对模块定义的规范化产出CommonJS是NodeJS使用的一种模块化方式RequireJSrequire.js是一个JavaScript文件和模块载入器实现了JS文件的异步加载,避免网页失去响应管理模块之间的依赖性,便于代码的编写与维护RequireJS流程简述使用requirejs时,会把所有的js都交给requirejs来管理,把data-main指向main.js通过在main.js里面定义的require方法或者define方法,requirejs会把这些依赖和回调方法用一个数据结构保存起来当页面加载时,requirejs会根据这些依赖预先把需要的js通过document.createElement的方法引入到DOM中由于依赖的JS也是按照requirejs的规范来写的,所以他们也会有define或者require方法,同意类似的第二步这样循环向上查找依赖,同样进行保存当js里需要用到依赖所返回的结果时(通常是一个键值对对象),requirejs便会把之前那个保存回调方法的数据结构里面的方法拿出来并且运行,然后把结果给需要依赖的方法特殊说明:本身依赖的模块会比本身先加载RequireJS基本使用异步加载同步加载,时间固定,按照代码的位置来。如果是异步加载,加载的时间不固定。配置主模块app.js变量名 require 和 requirejs完全一致baseUrl :配置公共路径paths :路径和名称的映射关系shim :解决模块不支持requirejs和前置依赖等其它问题引入模块定义模块模块名称的问题命名模块 | 匿名模块jQuery源码,Line:9806使用RequireJS定义模块的时候,’define()’函数有三个参数:参数一,字符串,代表模块的名称,如果填写了,则必须使用参数二,当前模块所依赖的其它模块参数三,回调函数,参数为依赖的模块对应的映射
本文仅代表作者观点,不代表百度立场。系作者授权百家号发表,未经许可不得转载。
育知同创教育
百家号 最近更新:
简介: 0元入学,两周免费试听
作者最新文章君,已阅读到文档的结尾了呢~~
amd规范和cmd规范
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
amd规范和cmd规范
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口&&1142 阅读
近年来,前端变的越来越重,页面中的javascript代码量上升了一个量级,为了便于维护和团队协作,模块化是必经之路。针对javascript模块化,业界逐渐产出两种方案AMD和CMD,它们有什么区别呢?看看大牛玉帛在知乎上的回答:。
其中最重要的区别是AMD是提前执行,CMD是延迟执行。
//by foio.github.io
//CMD 推崇依赖就近,代表为seajs
define(function(require,exports,module){
var a = require('./a');
a.doSomething();
var b = require('./b');
b.doSomething();
//AMD 推崇依赖前置,代表为requireJs
//by foio.github.io
define(['./a','./b'],function(a,b){
a.doSomething();
b.doSomething();
本篇文章我们实现一个自己的requreJS,我并不打算在源码中处理浏览器兼容性等细节,过于关注细节,反而会影响我们从宏观上理解代码机构。本文的目的是实现一个基本可用的javascript模块加载系统,带领读者理解要实现一个模块加载系统需要的知识结构。了解几种在网页中异步加载javascript的方案(可以参考),对理解本文有很大帮助。我提出如下两个基本问题:
(1).RequireJS是如何异步加载js模块
(2).RequireJS是如何处理模块间的依赖关系的(包括如何处理循环依赖)
接下来我就来分别分析这两个问题。在开始之前,我们先看一下本文中javascript代码的层次结构。
1. RequireJS是如何异步加载js模块
如果你看过,就会发现RequireJS用的就是其中的script dom element的方法。下面是具体实现的伪代码。
//by foio.github.io
//foioRequireJS的js加载函数
foioRequireJS.loadJS = function(url,callback){
//创建script节点
var node = document.createElement(&script&);
node.type=&text/javascript&;
//监听脚本加载完成事件,针对符合W3C标准的浏览器监听onload事件即可
node.onload = function(){
if(callback){
callback();
//监听onerror事件处理javascript加载失败的情况
node.onerror = function(){
throw Error('load script:'+url+& failed!&);
//插入到head中
var head = document.getElementsByTagName(&head&)[0];
head.appendChild(node);
2. RequireJS如何按顺序加载模块
用过RequireJS都知道,它主要就是两个函数require和define。其中define用于定义模块,require用于执行模块。
//by foio.github.io
define(id,['a','b'],function(a,b){
return function(){
a.doSomething();
b.doSomething();
//doSomething();
//logic.js
require(id,['c'],function(c){
return function(){
c.doSomething();
//doSomething();
要保证javascript模块的执行顺序,首先必须组织好依赖关系。
(1)组织依赖关系
为了组织RquireJS需要哪些数据结构呢?看起来无从下手,我们可以对问题进行拆分。
&1&.模块放在哪里,如何标记模块的加载状态?
moudules存储了所有已经开始加载的模块,包括加载状态信息、依赖模块信息、模块的回调函数、以及回调函数callback返回的结果。
//by foio.github.io
modules = {
state: 1,//模块的加载状态
deps:[],//模块的依赖关系
factory: callback,//模块的回调函数
exportds: {},//本模块回调函数callback的返回结果,供依赖于该模块的其他模块使用
&2&.正在加载但是还没有加载完成的模块id列表
每个脚本加载完成事件onload触发时,都需要检查loading队列,确认哪些模块的依赖已经加载完成,是否可以执行
//by foio.github.io
loadings = [
(2). define函数的基本实现
再次强调,本文的目的是理解结构,而不是具体实现,因此代码中不会考虑浏览器兼容性,也不会考虑逻辑的完整性。define函数主要目的是将模块注册到factorys列表中,方便require可以找到。同时必须处理循环依赖问题。
//by foio.github.io
foioRequireJS.define = function(deps, callback){
//根据模块名获取模块的url
var id = foioRequireJS.getCurrentJs();
//将依赖中的name转换为id,id其实是模块javascript文件的全路径
var depsId = [];
deps.map(function(name){
depsId.push(foioRequireJS.getScriptId(name));
//如果模块没有注册,就将模块加入modules列表
if(!modules[id]){
modules[id] = {
state: 1,//模块的加载状态
deps:depsId,//模块的依赖关系
callback: callback,//模块的回调函数
exports: null,//本模块回调函数callback的返回结果,供依赖于该模块的其他模块使用
(3). require函数的基本实现
require函数的实现是相当复杂的,我们先确立程序的基本框架,再逐步深入到具体细节。 其实require函数主要的逻辑就是将main模块放入modules和loadings队列。然后就开始调用loadDepsModule加载main模块的依赖模块。下面我们来看loadDepsModule的实现。
//by foio.github.io
foioRequireJS.require = function(deps,callback){
//获取主模块的id
id = foioRequireJS.getCurrentJs();
//将主模块main注册到modules中
if(!modules[id]){
//将主模块main依赖中的name转换为id,id其实是模块的对应javascript文件的全路径
var depsId = [];
deps.map(function(name){
depsId.push(foioRequireJS.getScriptId(name));
//将主模块main注册到modules列表中
modules[id]
state: 1,//模块的加载状态
deps:depsId,//模块的依赖关系
callback: callback,//模块的回调函数
exports: null,//本模块回调函数callback的返回结果,供依赖于该模块的其他模块使用
//这里为main入口函数,需要将它的id也加入loadings列表,以便触发回调
loadings.unshift(id);
//加载依赖模块
foioRequireJS.loadDepsModule(id);
可以说loadDepsModule是模块加载系统中最重要的函数了。 loadDepsModule函数主要是递归的加载一个模块的依赖模块,通过loadJS在dom结构中插入script元素来完成js文件的载入和执行。这里loadJS的callback函数也很值得研究。 每一个模块都是通过define函数定义的,由于callback函数在模块加载完成后才会执行,所以callback函数执行时模块已经存在于modules中了。相应的,我们也要将该模块放入loadings队列以便检查执行情况;同时递归的调用 loadDepsModule加载该模块的依赖模块。loadJS的在浏览器的onload事件触发时执行,这是整个模块加载系统的驱动力。
//by foio.github.io
foioRequireJS.loadDepsModule = function(id){
//依次处理本模块的依赖关系
modules[id].deps.map(function(el){
//如果模块还没开始加载,则加载模块所在的js文件
if(!modules[el]){
foioRequireJS.loadJS(el,function(){
//模块开始加载时,放入加载队列,以便检测加载情况
loadings.unshift(el);
//递归的调用loadModule函数加载依赖模块
foioRequireJS.loadDepsModule(el);
//加载完成后执行依赖检查,如果依赖全部加载完成就执行callback函数
foioRequireJS.checkDeps();
下面我们再来分析一下checkDeps函数,该函数在每次onload事件触发时执行,检查模块列表中是否已经有满足执行条件的模块,然后开始执行。checkDeps也有一个小技巧,就是当存在满足执行条件的模块时会触发一次递归,因为该模块执行完成后,可能使得依赖于该模块的其他模块也满足了执行条件。
//检测模块的依赖关系是否处理完毕,该函数在每一次js的onload事件都会触发一次
foioRequireJS.checkDeps = function(){
//遍历加载列表
for(var i = loadings.length, id = loadings[--i];){
var obj = modules[id], deps = obj.deps, allloaded =
//遍历每一个模块的加载
foioRequireJS.checkCycle(deps,id,colorbase++);
for(var key in deps){
//如果存在未加载完的模块,则退出内层循环
if(!modules[deps[key]] || modules[deps[key]].state !== 2){
allloaded =
//如果所有模块已经加载完成
if(allloaded){
loadings.splice(i,1); //从loadings列表中移除已经加载完成的模块
//执行模块的callback函数
foioRequireJS.fireFactory(obj.id, obj.deps, obj.callback);
//该模块执行完成后可能使其他模块也满足执行条件了,继续检查,直到没有模块满足allloaded条件
foioRequireJS.checkDeps();
最后我们分析一下,具体的执行函数fireFactory。我们知道,无论是require函数还是define函数,都有一个参数列表,fireFactory首先处理的问题就是收集各个依赖模块的返回值,构建callback函数的参数列表;然后调用callback函数,同时记录模块的返回值,以便其他依赖于该模块的模块作为参数使用。
//fireFactory的工作是从各个依赖模块收集返回值,然后调用该模块的后调函数
foioRequireJS.fireFactory = function(id,deps,callback){
var params = [];
//遍历id模块的依赖,为calllback准备参数
for (var i = 0, d = deps[i++];) {
params.push(modules[d].exports);
//在context对象上调用callback方法
var ret = callback.apply(global,params);
//记录模块的返回结果,本模块的返回结果可能作为依赖该模块的其他模块的回调函数的参数
if(ret != void 0){
modules[id].exports =
modules[id].state = 2; //标志模块已经加载并执行完成
这些内容是我用将近一周的业余时间的研究心得,希望对你有帮助。当然,这些代码都只是javascript加载系统的基本框架,如果有考虑疏忽的地方,还请你指正。文中的代码只是片段,完整的代码在我的github:
本文同时发表在我的博客 :
硕士毕业于中山大学,毕业后加入百度,曾参与百度地图用户中心后端系统的设计与研发,并主导百度国际化手机助手前端架构的设计,目前在腾讯QQ手机浏览器团队从事前端开发工作。专注web全栈架构领域!
个人博客:。}

我要回帖

更多关于 回调函数参数传递 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信