requireJS给我一个令人头疼的问题。 requireJS是AMD,根据定义,它说它是异步的。通常我会定义一个这样的模块。
define("some Name", ["./moduleOne"],function(moduleOne){
//this would be undefined
moduleOne.whatEver();
var aMethod = function(){
//user aModule.whatever();
}
return {
method: aMethod;
}
});
好吧,我知道我不能直接使用moduelOne.whatever因为它是异步加载的,如果调用回调则它不存在。
第一个问题,这是正确的吗?
现在,如果我将模块定义更改为:
define("some Name", function(require, exports){
var moduleOne = require(".moduleOne");
//this is OK
moduleOne.whatEver();
var aMethod = function(){
//user aModule.whatever();
}
exports.method = aMethod;
});
我可以直接使用aModule.whatever。当我从文档中读到时,使用这个(commonJS)样式,需要使用Function.prototype.toString解析函数,查看require语句并直接加载模块。
我很确定,我在这里误解了一些东西,如果有人可以解释究竟requireJS是如何工作的,以及第二种风格是否真的同步,那将是很好的。
由于
答案 0 :(得分:3)
你误解了它是如何运作的。
在两个示例中,您在问题中提供了执行顺序:
某些东西需要名为some_Name
的模块。 (我不认为RequireJS对包含空格的模块名称感到满意,所以我假设模块名称带有下划线。)
RequireJS查找模块some_Name
的依赖项和工厂函数。工厂是定义模块时define
给出的函数。
一个。如果define("some_Name"...
在此步骤之前被称为,则RequireJS只会获取给予define
的依赖项和工厂函数。
湾如果尚未执行define("some_Name"...
,则RequireJS将转到网络并尝试获取包含define
调用的文件并执行它。按照惯例,这将是一个与模块名称+ .js
扩展名相同的文件,但这可以在RequireJS配置中覆盖。
RequireJS检查是否加载了依赖项。如果没有,则它会针对尚未加载的每个依赖项发出require
次调用。
RequireJS使用已解析的依赖项调用工厂函数。
请注意,我没有在这里讨论所有可能的情况。我坚持使用最常见的案例来保持简单。
因此...
好吧,我知道我不能直接使用moduelOne.whatever因为它是异步加载的,如果调用回调则不存在。
第一个问题,这是正确的吗?
不,这不正确。在moduleOne.whatEver();
执行时,模块moduleOne
必须已加载已。如果moduleOne
为undefined
,则不,因为RequireJS具有异步性,但因为moduleOne
的定义存在错误。例如,如果它导出值undefined
,则moduleOne
将是未定义的。或者,您可能会获得undefined
的{{1}}值,这会在您尝试调用时导致错误,但这可能是由于忘记导出moduleOne.whatEver
而造成的。 / p>
第二种情况和第一种情况之间的区别在于第二种情况使用CommonJS糖语法,这导致上面的步骤2进行了一些额外的处理。在RequireJS执行工厂之前,它解析函数(如你所提到的),然后处理工厂函数,就好像已经按照这样调用定义的那样:
whatEver
define("some_Name", ['require', 'exports', './moduleOne'], function (require, exports) {
和require
模块是RequireJS内部定义的特殊模块。请注意RequireJS如何在依赖项列表的末尾添加exports
。完成后,该过程与第一种情况完全相同。
执行./moduleOne
时,模块已加载。所以这一行的作用仅仅是返回对模块的引用。