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?
define("name",["a","b","c"], function(a,b,c){
});
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".
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With