Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do AMD loaders work under the hood?

Tags:

javascript

amd

So I've been using require.js for while now, but I realized that I actually don't know how it works under the hood. It says that it's an AMD loader.

I do understand that CommonJS is synchronous, which means that it blocks execution of other codes while it's being loaded. On the other hand, AMD is asynchronous. This is where I get confused.

When I define a module, it has to load a,b,c in order to execute the callback. How does asynchronous work here?

  1. Isn't it synchronous when it has to load those three dependencies first?
  2. Does it mean that AMD loads a,b,c asynchronously then checks to see if those files are loaded (doesn't care about the order) then execute the callback?
define("name",["a","b","c"], function(a,b,c){

});
like image 203
Moon Avatar asked Aug 24 '12 23:08

Moon


2 Answers

As you know, "AMD" (Asynchronous Module Definition (AMD)) is a specific API. There are many AMD-compatible "loaders", including RequireJS, curl.js and Dojo (among others).

Just as frameworks like JQuery and Dojo give you an API over raw Javascript; a program that uses AMD:

1) requires you an AMD-compatible .js library,

2) demands certain programming "rules" and "conventions", and

3) Ultimately sits "on top" of Javascript, which runs on your "Javascript engine" (be it IE, Chrome, Firefox - whatever).

Here are a couple of links I found useful:

  • https://www.ibm.com/developerworks/mydeveloperworks/blogs/94e7fded-7162-445e-8ceb-97a2140866a9/entry/loading_jquery_with_dojo_1_7_amd_loader2?lang=en

  • http://dojotoolkit.org/reference-guide/1.8/loader/amd.html

  • http://blog.millermedeiros.com/amd-is-better-for-the-web-than-commonjs-modules/

  • http://addyosmani.com/writing-modular-js/

PS: To answer your immediate question, the latter link has a bit of discussion about "require()" and "dynamically_loaded dependencies".

like image 170
paulsm4 Avatar answered Nov 08 '22 14:11

paulsm4


Since I wrote an AMD loader, I'll try to answer the questions directly:

Isn't it synchronous when it has to load those three dependencies first?

Javascript, by definition, is single threaded. That means that anything you run in it always runs sequentially. The only thing that you can do in a browser is include scripts using the "async" parameter on the script tag, which will make the order in which scripts are being loaded undefined (asynchronous). Once a script executes it will be the only one executing at that point in time.

Does it mean that AMD loads a,b,c asynchronously then checks to see if those files are loaded (doesn't care about the order) then execute the callback?

Correct. AMD-define() allows you to load all scripts in any order you wish (i.e. ultimately you let the browser roll the dice and load them in any order it sees fit at any time it sees fit).

Then any time a define() is called, the AMD-loader will check if the current list of dependencies for this define has already been satisfied. If it is, it will call the current callback immediately, and after that, it will check if any of the previously registered define-callbacks can be called too (because all of their dependencies have been satisfied). If the dependencies for this callback have not all been satisfied yet, the callback is added to the queue to be resolved later.

This eventually results in all callbacks being called in the correct dependency order, regardless of the order in which the scripts have been loaded/executed in the first place.

like image 4
BuGless Avatar answered Nov 08 '22 14:11

BuGless