AMD加载器如何在引擎盖下工作?

时间:2012-08-24 23:38:20

标签: javascript amd

所以我现在一直在使用require.js,但我意识到我实际上并不知道它是如何工作的。它说这是一个AMD加载器。

我确实知道CommonJS是同步的,这意味着它在加载时会阻止其他代码的执行。另一方面,AMD是异步的。这是我感到困惑的地方。

当我定义一个模块时,它必须加载a,b,c才能执行回调。异步如何在这里工作?

  1. 当它必须首先加载这三个依赖项时是不是同步?
  2. 这是否意味着AMD异步加载a,b,c然后检查是否加载了这些文件(不关心顺序)然后执行回调?
  3. define("name",["a","b","c"], function(a,b,c){
    
    });
    

2 个答案:

答案 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(因为已经满足了它们的所有依赖关系)。如果尚未完全满足此回调的依赖性,则将该回调添加到队列中,以便稍后解决。

这最终导致所有回调均以正确的依赖关系顺序被调用,而不管脚本最初加载/执行的顺序如何。