为什么有同步和asynchronous模块的规范?
我刚读完这篇关于Javascript模块的文章 。 我可以理解,CommonJS模块是同步加载的,而AMD模块是asynchronous加载的。
我不明白的是,如果我使用CommonJS格式编写模块,那么我怎样才能使模块变得奇迹般地同步 ,或者如果我以AMD格式编写,它怎么变成奇迹般的asynchronous。 我的意思是JavaScript没有define
或甚至require
关键字。 他们只是规格而不是图书馆。
我的意思是模块加载的行为取决于模块加载器,而不是模块的结构。 如果是这样的话,为什么遵循不同types的模块的编码模式?
我是否认为NodeJS世界中的所有库都是同步加载的,而不pipe它们以什么格式写入。 浏览器空间中的所有模块都是asynchronous加载的。
如果我上面的假设是正确的,那为什么还有UMD的规格呢? 我的意思是如果一个脚本根据它所在的环境加载,那么为什么要为通用模块加载一个规范?
有人可以帮我解决这个问题吗?
这是一个很好的问题。 这是一个引起了Node社区热烈讨论的话题。 要很好地理解你所做的一切应该是:
- Node.js,TC-39,以及来自iBM的James M Snell的模块
- ES6模块互操作性 – Node.js增强build议
- 在.js的防御中 – Dave Herman,Yehuda Katz和CaridyPatiño提出的关于Node.js模块的build议
- 讨论节点-eps (002:ES6模块互操作)的合并请求#3
现在,回答你的问题 – 为什么有同步和asynchronous模块的规范? 因为一些用例更喜欢模块的同步加载,比如Node.js中的服务器端模块,在开始服务请求之前要加载所有需要的东西,而有些用例则喜欢asynchronous加载模块,比如在浏览器中在加载依赖关系时,不想阻塞呈现线程。
在浏览器中实际上没有select同步加载,因为它会使浏览器不响应。
你可能会争辩说,你可能会在服务器上使用asynchronous加载,但是这样你就不得不通过require()
返回promise而不是模块,否则可能需要callback。 无论哪种方式,它会使任何复杂的代码,使用大量的模块更加复杂。
另一个问题是已经加载的模块的caching和突变。 使用同步模块加载时,只require
加载模块一次,而对于整个代码库(对于该进程)中的同一个模块,任何其他调用都会返回一个caching的响应,每次都是相同的对象。 代码的任何部分都可以修改该对象,并可用于代码的任何其他部分。 一些使用该function的用例会比较复杂。 另外,加载和执行代码的顺序将更难预测。
总结你的问题的答案,有两种加载模块的方法的论点,这两种方式都不是每个场景的胜利者。 两者都是必要的,都有一些规范来标准化他们的行为。
阅读我链接的文章以获得更详细的理解。
我的意思是模块加载的行为取决于模块加载器,而不是模块的结构。 如果是这样的话,为什么遵循不同types的模块的编码模式?
模块是同步还是asynchronous加载取决于模块加载器,但模块必须能够使用模块加载器,因此必须包含与加载器通信的接口 。 你不能使用amd define
函数在node.js中加载模块。 你必须使用require
。
如果我上面的假设是正确的,那为什么还有UMD的规格呢? 我的意思是如果一个脚本根据它所在的环境加载,那么为什么要为通用模块加载一个规范?
脚本不会根据环境加载,而是通过加载器界面加载。 UMD用于人们在浏览器和服务器中使用的库。 图书馆作者不必创build两个版本的库,一个用于浏览器,一个用于节点,因为UMD
知道如何处理这两个版本。