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

问题描述:

我刚读完Javascript模块上的这个article。我可以理解CommonJS模块是同步加载的,而AMD模块是异步加载的。javascript - 为什么有同步和异步模块的规范?

我不明白的是,我怎么能模块成为神奇同步如果我把它写在CommonJS的格式,或者它是如何成为奇迹般地异步如果我把它写在AMD格式我的意思是JavaScript没有definerequire关键字甚至。他们只是规格而不是库。

我的意思是模块加载的行为取决于模块加载程序,而不是模块的结构。如果是这种情况,为什么遵循不同类型模块的编码模式?

我是否认为NodeJS世界中的所有库都是同步加载的,无论它们以什么格式写入。浏览器空间中的所有模块都是异步加载的。

如果我上面的假设是正确的,那为什么还有UMD的规范?我的意思是如果一个脚本根据它存在的环境加载,那么为什么要为通用模块加载做一个规范?

有人可以帮我解决这个问题吗?

+0

如何加载“模块”不会改变代码 - 你对模块内代码的假设是你的绊脚石 –

+0

@JaromandaX是的,那么为什么还有模块规格。你能详细说明你的意思吗? –

+0

模块本身并不是同步的,而是异步的,它只是调用什么样的加载器接口。 CJS格式假设一个同步加载器,在浏览器上不能很好地工作,所以AMD格式被创建为允许依赖声明与异步正文执行(回调)。 AMD也将与同步加载器一起工作。 – Bergi

这是一个很好的问题。这是一个在Node社区引起很多热烈讨论的主题。有一个什么样这一切都很好的理解你应该阅读:从IBM

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

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

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

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

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

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

+0

谢谢,但讲一件简单的事情。我在浏览器中写入了一个js,并通过任何异步加载器加载,这成为一个异步模块。但是我在NodeJS中使用相同的文件变成同步模块。所以我的观点是,为什么我应该遵循两个环境的规范,当它不重要时。另外AFAIK,'

我的意思是模块加载的行为取决于模块加载程序,而不是模块的结构。如果是这种情况,为什么遵循不同类型模块的编码模式?

该模块是同步或异步加载取决于模块加载,但你的模块必须能够使用一个模块加载,从而必须包括接口与装载机沟通。 使用amd define函数无法在node.js中加载模块。您必须使用require

如果我上面的假设是正确的,那为什么还有UMD的规范呢?我的意思是如果一个脚本根据它存在的环境加载,那么为什么要为通用模块加载做一个规范?

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