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

IT技术 javascript node.js asynchronous
2021-02-08 03:21:43

我刚刚读完这篇关于 Javascript module的文章我可以理解,CommonJS module是同步加载的,而 AMD module是异步加载的。

我不明白的是,如果我以 CommonJS 格式编写module,我如何才能神奇地同步,或者如果我以AMD 格式编写它,它如何神奇地变为异步我的意思是 javascript甚至没有defineorrequire关键字。它们只是规格而不是库。

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

我是否正确地假设 NodeJS 世界中的所有库都是同步加载的,无论它们是以什么格式编写的。并且浏览器空间中的所有module都是异步加载的。

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

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

2个回答

这是一个很好的问题。这是一个在 Node 社区引起了很多热烈讨论的话题。要很好地了解它的全部内容,您应该阅读:

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

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

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

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

总结您的问题的答案,两种加载module的方式都有争议,而且这两种方式都不是每种情况下的明显赢家。两者都是必需的,并且都有一些规范来标准化他们的行为。

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

谢谢,但告诉一件简单的事情。我在浏览器中编写了一个 js 并通过任何异步加载器加载它,它成为一个异步module。但是我在NodeJS中使用同一个文件变成了一个同步module。所以我的观点是为什么我应该在两个环境无关紧要的情况下遵循规范。同样 AFAIK,<script>标签在浏览器中提供同步加载,而加载器SystemJS提供异步加载,对吧?所以我的意思是你可以同步加载到浏览器中,对吗?
2021-03-15 03:21:43

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

module是同步加载还是异步加载取决于module加载器,但是您的module必须能够使用module加载器,因此必须包含与加载器通信的接口您不能使用 amddefine函数在 node.js 中加载module你必须使用require.

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

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