2

在 requirejs 中,您可以定义一个模块而无需按字面设置它的名称,例如:

//in a.js
define([/*deplist*/],function(){
    /*do something*/
});

//in b.js
define([/*deplist*/],function(){
    /*do something*/
});

并且 requirejs 会根据他们的文件名(“a”和“b”)设置他们的模块名。Requirejs 添加<script>您的应用程序需要的所有标签,它们不是按顺序加载的(正如网络时间线所说)。

js文件加载时间线

当一个模块调用define来定义自己时,它不知道它的模块名称,然后它将自己置于defQueue等待初始化的状态。初始化将在加载事件处理程序中完成,因为在事件处理程序函数中,节点引用是可访问的,并且模块名称记录在节点属性上(如:)<script type="text/javascript" charset="utf-8" async="" data-requirecontext="_" data-requiremodule="a" src="./a.js"></script>

这就是问题所在,我们无法保证模块调用的顺序define与模块的节点load事件触发的顺序一致。那么模块名称如何正确映射到模块工厂呢?

4

1 回答 1

1

事实证明,js 评估及其引用节点“加载”事件触发顺序是巧合。

一个模块的js文件加载后,里面的内容会被评估(不知道什么时候,但会按照js文件加载的顺序评估),然后requirejs会将工厂和依赖列表推送到FIFO队列中。浏览器会按照 js 文件加载的顺序触发节点加载事件,并且 requirejs 在 "load" 事件处理程序中链接模块 id 和它的工厂。

例如,如果 a.js 在 b.js 之前加载,那么 a.js 的内容将不迟于 b.js 的内容被评估,并且 a.js 的“加载”事件处理程序将不迟于 b.js 的被调用。然后可以确定模块的 id 映射到它们的工厂和依赖列表。

于 2013-03-11T02:18:32.250 回答