这篇随笔主要记录require('name')和require(['name1','name2'])在同步和异步加载使用的区别

1、require('name')同步加载模块的形式

define(function(require, exports, module) {
var a = require('a'),
b = require('b'); //Return the module value
return function () {};
}
);

(1)首先看上面的代码,使用了var a = require('a')这样的写法,这是一种同步调用模块的写法(因为加载a模块后直接返回而不必放在回调函数中使用), 说明此时在该define函数作用域里,模块a已被加载装配完毕,并可以通过require函数返回a模块,注意此时require函数中使用的参数是模块名而非数组;

(2)其次,该define函数是一种commonJS的简化写法,回调函数前并未声明依赖关系的数组,即并非define(['require','exports','module'],function(require, exports, module) {});这样的写法。此时require会使用

Function.prototype.toString() 对回调函数进行解析,并通过解析发现require('a')和require('b')。由于在调用回调函数之前,require会预先加载模块的所有依赖,所以在调用回调函数前会预先装配a模块和b模块,因此在调用require('a')和require('b')时,a和b模块已经提前装配好了;

(3)此外还需要注意的是,当define函数声明依赖关系数组时,当需要在回调函数使用var a = require('a')这样的写法时必须要将所需的模块a添加到依赖关系数组中,因为当define包含依赖关系数组时,require会将依赖关系数组中的依赖视为回调函数所需的所有依赖,即上面的代码就应改为如下形式,否则会报依赖关系没有加载的错误:

define(['require','exports','module','a','b'],function(require, exports, module) {
var a = require('a');
b = require('b'); //Return the module value
return function () {};
}
);

(4) 由于使用require('name')的原理是将所需的依赖预先加载然后再能进行调用,所以不能再全局作用域中使用var a = require('a')这样的写法,这样的写法必须包含在define或require([...],function(){})的回调函数中;

(5)由于使用commonJS写法时,require检测依赖关系的机制是通过调用Function.prototype.toString() ,所以不能使用以下写法,否则会报依赖关系没有加载的错误:

define(function(require, exports, module) {
var a = getRequireModule(require, 'a');
b = getRequireModule(require, 'b'); //Return the module value
return function () {};
}
); function getRequireModule(require, moduleName) {
return require(moduleName);
}

2、 require(['name1', 'name2'])异步加载模块的形式

(1)通过require([...])形式获取模块的依赖,和上面不同的是,调用require函数使用的参数是数组而非模块名,这种调用方式是异步调用的方式,即不能使用var a = require(['a'])这样的方式同步返回一个模块,require(['a'])返回的是一个函数,而非a模块向外部暴露的接口,应该在回调函数中使用模块a,即如下的方式才是正确的:

define(['a'], function(a) {
console.log(a);
})

(2)和require('a')的另一个区别是,由于require(['a'])是一种异步依赖模块的方法,所以在使用commonJS简化的define写法时,加载依赖关系时不会检测到['a']中所包含的a模块

(3)由于异步加载的关系,所以在使用时仍应注意有两种情况:

1、当依赖的模块遵循AMD规范时,该模块将会被包含在define函数中,会拥有自己的作用域和向外部暴露的接口,需要通过回调函数才能使用这些模块向外提供的接口;

2、当依赖的模块不遵循AMD规范时,该模块被加载后,由于模块中的js代码具有全局作用域,理论上能够在外部而不必在回调函数中使用模块的接口,但是由于模块是异步加载的,在使用依赖模块提供的接口时,在外部无法保证模块是否已加载完毕,所以仍然应在回调函数中使用依赖模块。

(4)当require调用需要使用回调函数时,正确的写法应该是:

    require(['dependency'], function (dependency) {});

写成require('dependency', function (dependency) {});   是错误的

关于requireJS的同步加载和异步加载的更多相关文章

  1. 【UE4 C++ 基础知识】<11>资源的同步加载与异步加载

    同步加载 同步加载会造成进程阻塞. FObjectFinder / FClassFinder 在构造函数加载 ConstructorHelpers::FObjectFinder Constructor ...

  2. javascript 同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值. defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面 ...

  3. Javascript 文件的同步加载与异步加载

    HTML 4.01 的script属性 charset: 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer: boolean, 可选.延迟脚本执行,相当于将script标签放入页面b ...

  4. AJAX中的同步加载与异步加载

    AJAX是四个单词的简写,其中Asynchronous即异步的意思,异步的链接可以同时发起多个,并且不会阻止JS代码执行.与之对应的概念是同步,同步的链接在同一时刻只会有一个,并且会阻止后续JS代码的 ...

  5. Jquery前端分页插件pagination同步加载和异步加载

    上一篇文章介绍了Jquery前端分页插件pagination的基本使用方法和使用案例,大致原理就是一次性加载所有的数据再分页.https://www.jianshu.com/p/a1b8b1db025 ...

  6. 动态加载(异步加载)jquery/MUI类库 页面加载完成后加载js类库

    动态加载Mui类库: // ==UserScript== // @name // @version 1.4.0 // @author zzdhidden@gmail.com // @namespace ...

  7. JS的同步加载、异步加载

    在使用js展开式菜单时,发现只有加载完页面包含的js文件时,展开菜单才能折叠起来. 查找了一下原因:是因为js页面加载使用的是同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前 ...

  8. 图解script的三种加载方式 异步加载顺序

    摘录如下: 可以很清晰的看出: <script>: 脚本的获取和执行是同步的.此过程中页面被阻塞,停止解析. <script defer = "defer"> ...

  9. [原创]cocos2dx加载网络图片&异步加载图片

    [动机] 之前看到一款卡牌游戏,当你要看全屏高清卡牌的时候,游戏会单独从网络上下载,本地只存了非高清的,这样可以省点包大小,所以我萌生了实现一个读取网络图片的类. [联想] 之前浏览网页的时候经常看到 ...

随机推荐

  1. 转载 Some indexes or index [sub]partitions of table VAS.TAB_PUB_CALLLOG have been marked unusable

    http://www.xifenfei.com/2011/12/some-indexes-or-index-subpartitions-of-table-vas-tab_pub_calllog-hav ...

  2. =与==、&与&&、| 与 || 的区别

    =与== =属于赋值运算符,将右侧的值赋给左侧的变量名称 ==属于关系运算符,判断左右两边值是否相等,结果为boolean类型 &与&& &是逻辑与,&& ...

  3. Idea创建Maven项目没有src

    第一次创建,下载非常慢,解决方法 1.配置环境变量 第二种:创建Maven项目时加上 archetypeCatalog=internal 参数 第三种:为自己的Maven配置国内镜像源 打开自己的 M ...

  4. Android中的APinner2

    Spinner提供了从一个数据集合中快速选择一项值的办法.默认情况下Spinner显示的是当前选择的值,点击Spinner会弹出一个包含所有可选值的dropdown菜单,从该菜单中可以为Spinner ...

  5. C# list.toArray list与数组的转换

    void Start () { List<int> list = new List<int>(); list.Add(); list.Add(); list.Add(); li ...

  6. Murano Weekly Meeting 2016.07.12

    Meeting time: 2016.July.12 1:00~2:00 Chairperson:  Kirill Zaitsev, from Mirantis Meeting summary: 1. ...

  7. Python 多继承(新式类) 的mro算法

    转载自:http://www.cnblogs.com/panyinghua/p/3283831.html mro即method resolution order,主要用于在多继承时判断调的属性的路径( ...

  8. VMware 虚拟机(linux)增加根目录磁盘空间

    VMware 虚拟机(linux)增加根目录磁盘空间     今天查看学校的监控报修系统,不能访问了!!!系统运行很慢,用top命令查看发现内存使用率90%,用"df -h ”查看“/”目录 ...

  9. 【转】Android实现伸缩弹力分布菜单效果

    本文介绍下在Android中实现伸缩弹力分布菜单效果.关于这种菜单效果在IPhone中比较常见,效果比较酷.那么在Android中实现只是一种简单的模仿. 这两天无意间看到一园友的博文实现Path2. ...

  10. CentOS7 安装oracle 客户端

    参考 http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html   下载 oracle-instantclient11. ...