javascript - 为什么有同步和异步模块的规范?

时间:2016-11-10 08:34:04

标签: javascript node.js asynchronous

我刚刚在Javascript模块上阅读了这个article。我可以理解,在异步加载AMD模块的同时,CommonJS模块是同步加载的。

我不明白的是,如果我以CommonJS格式编写模块,我怎么能变成神奇同步,或者如果我把它写在< em> AMD格式。我的意思是javascript甚至没有definerequire关键字。它们都是规格而不是图书馆。

我的意思是模块加载的行为取决于模块加载器而不是模块的结构。如果是这样的话,为什么要遵循不同类型模块的编码模式呢?

我是否正确地假设NodeJS世界中的所有库都是同步加载的,无论它们采用何种格式编写。并且浏览器空间中的所有模块都是异步加载的。

如果我的上述假设是正确的,为什么甚至有UMD的规范?我的意思是,如果脚本根据它所存在的环境加载,那么为什么要为通用模块加载制作规范呢?

有人可以帮我解决这个困惑吗?

2 个答案:

答案 0 :(得分:4)

这是一个很好的问题。这是一个在Node社区引起很多激烈讨论的主题。要充分了解它的全部内容,请阅读:

现在,回答你的问题 - 为什么有同步和异步模块的规范?因为一些用例更喜欢模块的同步加载,比如Node.js中的服务器端模块,你想在开始提供请求之前加载你需要的所有东西,有些用例更喜欢异步加载模块,比如在浏览器中在加载依赖项时,我们不想阻止渲染线程。

浏览器中没有选择同步加载的选项,因为它会使浏览器无法响应。

你可能会争辩说你可能在服务器上使用异步加载但是你要么必须通过require()返回promises而不是模块,否则它可能需要回调。无论哪种方式,它都会使使用大量模块的任何复杂代码变得更加复杂。

另一个问题是已经加载的模块的缓存和变异。使用require加载同步模块时,只需加载 对于整个代码库中的相同模块(对于该进程),模块一次和任何其他对require的调用返回一个缓存的响应,每次都是相同的对象。代码的任何部分都可以修改该对象,并且它可用于代码的任何其他部分。一些使用该功能的用例实现起来要复杂得多。此外,加载和执行代码的顺序将更难预测。

总结你的问题的答案,有两种加载模块的方法的论据,这两种方式都不是每个场景的明显赢家。两者都是必需的,并且都有一些规范来规范他们的行为。

阅读我链接的文章以获得更详细的理解。

答案 1 :(得分:1)

  

我的意思是模块加载的行为取决于模块加载器而不是模块的结构。如果是这样的话,为什么要遵循不同类型模块的编码模式呢?

模块是同步加载还是异步加载取决于模块加载器,但模块必须能够使用模块加载器,因此必须包含 interface 以与加载器通信。 您无法使用amd define函数在node.js中加载模块。您必须使用require

  

如果我的上述假设是正确的,为什么甚至有UMD的规范?我的意思是,如果脚本根据它所存在的环境加载,那么为什么要为通用模块加载制作规范呢?

脚本不会根据环境加载,而是通过加载器接口加载。 UMD适用于人们在浏览器和服务器中使用的库。图书馆作者不必创建两个版本的库,一个用于浏览器,一个用于节点,因为UMD知道如何处理这两个版本。