【问题标题】:Are Asynchronous Modules Always Asynchronous?异步模块总是异步的吗?
【发布时间】:2014-04-10 14:49:24
【问题描述】:

当多个 JavaScript 模块使用 AMD define()'d 并连接到一个文件中时,这些模块是否仍被视为异步?

【问题讨论】:

    标签: javascript requirejs amd commonjs browserify


    【解决方案1】:

    一般来说,只是将一堆 AMD 模块连接在一起不会使它们同步。但是,如果您可以忍受额外的限制并选择可以执行此操作的加载器,则可以同步加载 AMD 模块。

    RequireJS

    我不知道 RequireJS 会同步加载任何东西的情况,即使不需要异步加载。您可以在 <script> 标记中包含以下内容:

    define("foo", [], function () {
    });
    
    require(["foo"], function (foo) {
    });
    

    这里没有什么可以加载的,因为所有的代码都已经存在了。 foo 模块不需要从任何地方获取。它的依赖列表是已知的,等等。然而,RequireJS 会异步处理它。

    对于一些想知道 RequireJS 同步加载模块的能力的人来说,混淆的一个来源可能是 RequireJS 的require 同步形式。你可以这样做:

    define(function(require) {
        var foo = require("foo");
    });
    

    这里对 require 的调用看起来是同步的,但 RequireJS 通过将 "foo" 添加到 define 所需模块的列表中,将其在后台转换为同步:

    define(["foo"], function(require) {
        var foo = require("foo");
    });
    

    所以虽然require 调用看起来是同步的,但 RequireJS 仍然异步处理它。

    杏仁

    Almond 是 RequireJS 的作者 James Burke 做的一个加载器,可以同步加载 AMD 模块。现在,Almond 有一系列限制。一个这样的限制是您不能动态加载任何内容。也就是说,您要加载的整个模块列表必须是您使用 r.js 创建的优化包的一部分,并提供给 almond 进行加载。如果你能忍受 almond 的限制,那么同步加载一堆 AMD 模块是很有可能的。我在answer 中提供了有关如何执行此操作的详细信息。

    【讨论】:

    • 感谢您提供的详细信息。程序的内存占用是否会受到是否使用同步/异步的影响(再次假设所有模块都已存在于文件中)?
    • 同步和异步方案之间的唯一区别是加载程序的大小。 Almond 比 RequireJS 小很多。
    【解决方案2】:

    是的,它们仍然被认为是异步的。

    虽然模块本身不必从磁盘加载,但确实需要执行模块并进行回调。

    因为您可以将 SOME 模块组合到一个文件中并不意味着您必须将所有模块组合在一起——RequireJS 也不假设所有模块都存在。

    它将从您的预加载中运行它可以运行的内容并异步加载其余部分。

    【讨论】:

    • 很好的答案,谢谢。你知道什么时候模块被认为是“在内存中”(即,当它被加载与何时执行)?
    • 在收到回调之前,您不能假设模块已加载。如果您需要一个模块,请确保始终在您的 requiredefine 语句中使用它——如果您依赖链中较早的内容加载它,您可能会遇到竞争条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多