自制异步模块加载器
https://github.com/youngwind/blog/issues/98
http://www.ruanyifeng.com/blog/2015/11/circular-dependency.html
从阮一峰的上文了解到,commonjs加载时,实际上每require时就已经在执行那个文件了。如遇循环引用,比如a引用b, b再引用a。那么b引用a时,只会输出已经执行的部分,还未执行的部分不会输出。并且exports的结果会缓存。
而es6的话,它遇到模块加载命令import时,不会去执行模块,而是只生成一个引用。等到真的需要用到时,再到模块里面去取值。也不会缓存运行结果,而是动态地去被加载的模块取值,以及变量总是绑定其所在的模块。(所以实际上现在我们代码中写的import会被编译成require,所以还是commonjs的表现?缓存js以及一开始就执行?)
而requirejs的话,如果你定义了一个循环依赖(a依赖b,b同时依赖a),则在这种情形下当b的模块函数被调用的时候,它会得到一个undefined的a。b可以在模块已经定义好后用require()方法再获取(记得将require作为依赖注入进来):
讲到实现,关键就是有模块这一类:
原文很好的运用了setter!
以ModuleA为例子,首先ModuleA定义自己的depCount(依赖长度),如果depCount===0那么则在depCount的setter中开始执行ModuleA模块。模块A执行成功后,设置Module.STATUS,并在STATUS的stter中进行如下操作:过对象mapDepToModule,查找到依赖包括该模块的所有模块,那么让那些模块都执行depCount--。
更多可日后再补:https://www.jianshu.com/p/0505b1718dab