所以我现在一直在使用require.js,但我意识到我实际上并不知道它是如何工作的。它说这是一个AMD加载器。
我知道CommonJS是同步的,这意味着它在加载时会阻止其他代码的执行。另一方面,AMD是异步的。这是我感到困惑的地方。
当我定义一个模块时,它必须加载a,b,c才能执行回调。异步如何在这里工作?
define("name",["a","b","c"], function(a,b,c){
});
如您所知,“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依赖”的讨论。
自从我编写AMD加载器以来,我将尝试直接回答这些问题:
当它必须首先加载这三个依赖项时,它不是同步的吗?
根据定义,Javascript是单线程的。这意味着您在其中运行的任何内容始终按顺序运行。您可以在浏览器中执行的唯一操作是包含脚本标记上使用“async”参数的脚本,这将使脚本的加载顺序为undefined(异步)。一旦脚本执行,它将是唯一一个在该时间点执行的脚本。
这是否意味着AMD异步加载a,b,c然后检查是否加载了这些文件(不关心顺序)然后执行回调?
正确。 AMD-define()允许你以任何你想要的顺序加载所有脚本(也就是说,最终你让浏览器掷骰子并按照它认为合适的任何顺序加载它们)。
然后,只要调用define(),AMD-loader就会检查是否已满足此定义的当前依赖关系列表。如果是,它将立即调用当前回调,之后,它将检查是否也可以调用任何先前注册的define-callback(因为它们的所有依赖关系都已满足)。如果尚未满足此回调的依赖关系,则将回调添加到队列中以便稍后解决。
这最终导致以正确的依赖顺序调用所有回调,而不管首先加载/执行脚本的顺序如何。