-
Notifications
You must be signed in to change notification settings - Fork 228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
没有把依赖的模块作为回调函数的参数时,导致依赖的模块的factory函数不执行 #20
Comments
是的。在1.8版本以上,esl的module定义策略是 |
这种依赖某个模块,但是不会使用该模块的场景是哪些? |
我们暂时没有发现依赖一个模块,但是不用的情况。
另外,使用amd进行开发,在开发时我们有一些practice,主要有几点:
详细可以参考这里:https://github.com/ecomfe/spec/blob/master/module.md |
我看了你们的模块和加载器规范之后,我有一个疑惑,当这种模块定义的写法 //define mod
define( function( require ) {
require("dep1");
require("dep2");
//....
}); 采用CMD这样定义模块的方法去定义一个模块的时候,再用esl加载这样的模块时,仍旧还是按照_AMD_的规则进行加载吗? 我试了下: //a.js
define('a',[],function(){
console.log('a factory call');
});
//b.js
define('b',[],function(){
console.log('b factory call');
});
//all.js
define('all',['a','b'],function(a,b){
// 执行时所有的依赖都加载完毕
console.log('all factory call begin')
//----
console.log('all factory call over')
})
//use
require(['all'], function() {
console.log('all callback');
})
//result
a factory call a.js:2
b factory call b.js:2
all factory call begin all.js:2
all factory call over all.js:4
all callback 但是当我用上面CMD的模块定义方法定义模块时 //a.js
define(function(require){
console.log('a factory call');
});
//b.js
define(function(require){
console.log('b factory call');
});
//all.js
define(function(require){
// 执行时所有的依赖还没加载吧?
console.log('all factory call begin')
require('a');
require('b');
console.log('all factory call over')
})
//result
all factory call begin all.js:2
a factory call a.js:2
b factory call b.js:2
all factory call over all.js:5
all callback 可以看到这种定义的方法和运行结果好像已经是CMD的样子,那esl是AMD加载器,可是好像是按照CMD的机制在运行。 如果执行factory的时候,并没有提前执行依赖,这好像不是AMD的行为,我用requirejs执行了上述的例子,requirejs无论上述哪种写法都是按照AMD的“依赖提前执行”这个规则来执行的,而esl则是截然不同的结果。难道esl对后一种写法(CMD写法)其实就是按照CMD规则来加载,对前一种写法(AMD写法)就是按照AMD规则来加载? 也许我的理解是有问题的,只是突然有点晕... |
requirejs我记得从某个版本开始也是延后执行factory的:requirejs/requirejs#183 另外AMD并没有规定factory的执行时机,无论是加载后执行还是第一次require时执行,都不违反AMD的标准,而CMD是规定了factory 必须 延后执行而已 |
其实我提出的问题不是factory是define的时候执行还是第一次requrie的时候执行,目前requirejs也是第一次require的时候执行的。 我提出的问题是在执行一个模块的factory的时候,是否提前执行该模块所依赖的模块的factory,CMD是你requrie某个依赖的模块时候,才开始执行这个依赖模块的factory;而AMD是在执行该模块的factory之前提前把所依赖的模块都加载了,也就是所依赖的模块的factory要是没执行,都会提前执行了。 通过测试,当模块按照上述第二种方法,即CMD的模块定义的方法定义的时候,用esl加载模块时,当模块加载的时候,该模块的依赖的模块不会在该模块的factory执行之前加载,而是当用require调用的时候才加载;这种方法加载的结果我对比了下seajs,结果是完全一致的;而requirejs无论哪种方法定义都不会变。 |
首先,下面两种方式都是AMD的模块定义方式。当然,第二种方式也是CMD的模块定义方式。可以看出,从模块定义的书写上,CMD是AMD的子集。在具体项目中,我们号称使用AMD,通常开发时按第二种方式书写,上线前通过相关工具打包成第一种方式的代码。 define('all',['a','b'],function(a,b){
console.log('all factory call begin')
console.log('all factory call over')
})
define(function(require){
console.log('all factory call begin')
require('a');
require('b');
console.log('all factory call over')
}) 然后,你的问题是关于factory call的时机。 在AMD spec里,对指定dependencies的场景,有相应描述:
我是这么理解的,对于factory中的形式参数,loader应该对dependencies里的声明模块,先执行factory初始化好,然后按顺序传递给factory。但是,当factory的形式参数数目少于3时,loader可以根据参数数量的前几个dependencies模块,去call factory。也就是说,dependencies数组里,后面一些模块的初始化时机,是可以 然后是AMD对define中的同步require的描述:
define(function (require) {
var a = require('a');
});
这里只说了loader可以去parse出require的模块,去加载它,然后执行依赖模块,然后 而且,就算不看AMD spec,只看requirejs,它也是有循环依赖的处理机制的。循环依赖出现的情况,是没法保证module factory运行的时候,dependencies全部加载完毕的。 综上,AMD对于 至于CMD,其明确强制规定了 |
非常感谢@errorrik细致的讲解,学到了很多,谢谢。 |
当define一个模块时,没有把依赖的模块作为回调函数的参数时,导致依赖的模块的factory函数不执行,例如:
The text was updated successfully, but these errors were encountered: