所以我现在一直在使用require.js,但我意识到我实际上并不知道它是如何工作的。它说这是一个AMD加载器。
我确实知道CommonJS是同步的,这意味着它在加载时会阻止其他代码的执行。另一方面,AMD是异步的。这是我感到困惑的地方。
当我定义一个模块时,它必须加载a,b,c才能执行回调。异步如何在这里工作?
define("name",["a","b","c"], function(a,b,c){
});
答案 0 :(得分:10)
如您所知,“AMD”(异步模块定义(AMD))是一种特定的API。有许多兼容AMD的“加载器”,包括RequireJS,curl.js和Dojo(以及其他)。
正如JQuery和Dojo这样的框架为您提供原始Javascript的API;一个使用AMD的程序:
1)需要一个与AMD兼容的.js库,
2)要求某些编程“规则”和“约定”,以及
3)最终坐在Javascript的“顶部”,它运行在你的“Javascript引擎”(无论是IE,Chrome,Firefox - 无论如何)。
以下是我发现有用的几个链接:
PS: 要回答您的直接问题,后一个链接有一些关于“require()”和“dynamic_loaded依赖”的讨论。
答案 1 :(得分:2)
自从我写了AMD加载程序以来,我将尝试直接回答问题:
当它必须先加载这三个依赖项时,它不是同步的吗?
根据定义,JavaScript是单线程的。这意味着您在其中运行的所有内容始终会顺序运行。您只能在浏览器中执行的操作是使用脚本标签上的“ async”参数包含脚本,这将使脚本的加载顺序不确定(异步)。一旦脚本执行完毕,它将是该时间点上唯一执行的脚本。
这是否意味着AMD异步加载a,b,c,然后检查是否已加载这些文件(不关心顺序),然后执行回调?
正确。 AMD-define()允许您以希望的任何顺序加载所有脚本(即最终让浏览器掷骰子并以其认为合适的任何顺序加载它们)。
然后,每次调用define()时,AMD-loader都会检查是否已满足该定义的当前依赖关系列表。如果是,它将立即调用当前回调,然后,它将检查是否也可以调用任何先前注册的define-callback(因为已经满足了它们的所有依赖关系)。如果尚未完全满足此回调的依赖性,则将该回调添加到队列中,以便稍后解决。
这最终导致所有回调均以正确的依赖关系顺序被调用,而不管脚本最初加载/执行的顺序如何。