Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: Is 'require' synchronous method in AMD (asynchronous module definition)?

Is 'require' synchronous in AMD (asynchronous module definition)? If so, what makes this specification asynchronous? What if I have require() (and it hasn't been loaded yet) in the middle of my code, will it stall execution? Talking browser-side.

like image 485
seunje Avatar asked Sep 29 '12 16:09

seunje


People also ask

Is JavaScript is synchronous or asynchronous?

JavaScript is a single-threaded, non-blocking, asynchronous, concurrent programming language with lots of flexibility.

What is AMD in require JS?

Asynchronous module definition (AMD) is a specification for the programming language JavaScript. It defines an application programming interface (API) that defines code modules and their dependencies, and loads them asynchronously if desired.

What do you mean by JavaScript is synchronous?

Synchronous code runs in sequence. This means that each operation must wait for the previous one to complete before executing. console.


2 Answers

There are two different synchronous concepts here. The first is "Will it stop my entire webpage, and sit and wait for the file.".

The answer is no. RequireJS doesn't do that if you've got a script with dependencies.

If you use it appropriately, it uses a promise-system. What that means is that if you send in your callback and define your requirements for that file, the callback won't be run until all of the required files are loaded.

If there's a require inside of one of those required files, then THAT callback won't be run until ITS dependencies have loaded.

The outermost callback (the one that would be at the bottom of your script, normally), won't run until everything inside has.

This works on a promise system. It's worth understanding how promise systems work (similar to an observer-pattern, in a way). They're meant to be passed around or chained, based on an event, rather than having multiple people listen in any order.

var widget = new Widget(),  
    widgetLoaded = widget.load(url); // return a promise to let the program use the widget

widgetLoaded.then(function () { widget.move(35); })
            .then(function () { widget.setColour("Blue"); })
            .then(function () { widget.show(); });

This is like returning this so that you can chain function calls, except that the calls don't actually happen until widget.load() completes.

The widget will actually control when this happens, by keeping its promise if the widget loads and everything is fine, or by breaking its promise if something went wrong.

In most promise systems, .then or whatever they call it, either takes two functions (kept and broken -- in my systems, brokens are always optional), or they take an object with success and failure -- $.ajax does this, and then lets you predetermine what you want to do with the data when it's loaded, or if it fails -- promises.

So your page still work 100% asynchronously (without interrupting the UI), but it's 100% synchronous in that all of the modules will fire in the right order.

One thing you MUST REMEMBER: If you have these dependencies in your code, you can not have any dependencies lying around at the bottom of your script, waiting to run, inline. They must all be locked away inside of your callback, or locked inside a function waiting to be called by your callback.

This is simply because it is an asynchronous process, in terms of actual processing, and will not block the browser from running events/JS, rendering the page, et cetera.

like image 67
Norguard Avatar answered Sep 30 '22 22:09

Norguard


For requireJS:

You have to pass a callback method alongside the required modules to .require(), that will get fired when the resources were loaded successfully. So, of course you should/can only access loaded AMD or CommonJS modules just within that callback.

for NodeJS:

Yes, .require() does work synchronously. NodeJS uses the CommonJS module system, not AMD.

like image 36
jAndy Avatar answered Sep 30 '22 21:09

jAndy