为什么有同步和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知道如何处理这两个版本。