Dojo require with single argument synchronous? - javascript

My company is moving from classic Dojo syntax to AMD. We have a few situations where we need to dynamically load modules synchronously.
Require in dojo doesn't seem to officially support synchronous loading (at least it's not documented anywhere) but it seems to work if you don't pass in the a function as the second argument (in 1.7.2 at least).
require(["path/to/my/Module"]);
I've added extra latency in Fiddler and it's definitely loading before moving onto the next line.
Does anyone know if this is safe to rely upon? I don't particularly want to litter the codebase with this if it's just a hangover from the classic style that'll be retired in 2.0.

AMD does not support synchronous loading even when using commonJs style requires. The require function will only load synchronously if the module has already been loaded. See:
AMD API: https://github.com/amdjs/amdjs-api/wiki/require#requirestring
See also: require.js synchronous
If you have already loaded the module asynchronously then it is possible to use commonJs style requires, eg:
var lang = require("dojo/_base/lang");
However, if you have not already loaded it, it will throw an undefinedModule error (I've testet this in v1.9). If this works in v1.7 then this has been fixed in later editions of Dojo.
It is not possible to temporarily put it into synchronous mode either by passing a new config to Dojo, eg:
require({"async":false});
The async setting can only be set at load time (see: http://dojotoolkit.org/reference-guide/1.9/loader/amd.html#loader-amd-configuration). Hence, you select either asynchronous or synchronous at the initial load and then you are stuck there.
I would advise refactoring any code that requires synchronous operation. This is usually possible and the result will be probably be better and quicker code.

Related

What does synchronous vs asynchronous loading mean?

Reading from this site, I understand that using commonjs means that when the browser finishes downloading your files, it will have to load them up 1 by 1 as they depend on each other. But with AMD, it can load multiple ones at the same time so that even if file a depends on file b, it part of file a can be executed before file b is finished?
CommonJS Modules: The dominant implementation of this standard is in
Node.js (Node.js modules have a few features that go beyond CommonJS).
Characteristics: Compact syntax Designed for synchronous loading and
servers
Asynchronous Module Definition (AMD): The most popular
implementation of this standard is RequireJS. Characteristics:
Slightly more complicated syntax, enabling AMD to work without eval()
(or a compilation step) Designed for asynchronous loading and browsers
Synchronous programming is executing code line by line. Same with loading.
It will load 1 by 1 whatever that you are loading.
Real world example: You are in a queue in cinema for a movie ticket.
Asynchronous would be many people in restaurant. You order food and other people order food. They dont need to wait for your order to finish.
Everyone can order but you dont know when the order will come. Same as with loading. You can load multiple things at the same time or different intervals but it doesnt guarantee that it will come in that order.
I hope the explanation is good enough.
The syntax with CommonJS in loading modules is as such:
var MyModule = require("MyModule");
As you can see, this will block the thread until the module is downloaded, from either your filesystem or the web. This is called synchronous loading. This is impossible to achieve in a normal web browser environment without affecting user experience, since we cannot block the thread as the browser uses the thread to update the graphics.
With RequireJS, it's done as such:
// In your module
define(["dependencies", ...], function(){
return MyModule;
})
// In your web page
require(["dependencies", ...], function(MyModules, ...){
// do stuff here
});
With this model, our web page does not depend on the timing of when the module should be loaded. We can load our scripts in parallel while the page is still being loaded. This is called asynchronous loading. Once the scripts are loaded, they will call define which notifies RequireJS that the scripts are indeed loaded and executed. RequireJS will then call your main function and pass in the initialized modules.

Can/will AMD modules load in-between in-line script tags?

For reasons that aren't relevant to the question, my coworker needs to load a script that uses the Universal Module Definition pattern. Our environment usually has an AMD tool loaded, but for more irrelevant reasons, my coworker needs the script to define a global rather than registering a module through AMD. The approach that is currently checked in on their branch is something along the lines of this:
<script>
var backupDefine = define;
define = null;
</script>
<script src="../path/to/some/script/using/UMD.js"></script>
<script>
define = backupDefine;
backupDefine = null;
</script>
My question is: Is this a horrible idea? Is there a guarantee in the way browsers load scripts from script tags that will ensure nothing other than loading the UMD-based script will happen between undefining define and restoring define? We have a very large, very heavily async asset load primarily based around AMD modules, so what I am concerned with is an AMD module attempting to define itself in that intermittent state where define is currently not defined.
So long as UMD.js in no way modifies the scripts in the DOM, those scripts are guaranteed to execute in the order that they're authored in before any asynchronous callbacks that may have been queued before the first script executes.
I see this as a bad idea and spec breaking even if the case where define is always necessary is rare or even non-existent due to <script> load order considering your case. In an AMD environment, define, require and the like should basically be treated as first class keywords since their goal is to help you to remove globals.
Realistically, you're treading into undefined behavior as far as I can tell and writing code that is hard to maintain. You're relying on a tricky case with a spec where you have to undefine something and them immediately redefine it hoping that nothing tried to use it in the mean time. I'd say that that's "unsafe".
If you really need this to happen, I'd comment and document it heavily to make sure a future developer doesn't misunderstand what you're doing. However, I would say the better course of action is to rewrite the UMD.js file so that you export your global your own way. Rhetorically, why are you trying to use UMD if you don't want it to UMD things?
You're writing this module to support AMD through UMD but then you say that you don't want it to be used by AMD. Rewrite the file to just export to the global and avoid messing with define before you accidentally conflict with an additional library that does something tricky with define.

What is exactly define(function(require){...}) in JavaScript

I understand that define is used to define a module, and function is an anonymous function, but what does the argument 'require' in the function hold?
If I write anything in define(function(require){...}), when will this be called? How to give a call to his anonymous function?
Please help, I am new to advanced JS.
This is part of the requireJs api, it's not vanilla JS.
You can see the full docs in here:
http://requirejs.org/docs/api.html#define
"require" in the above example is actually the "require" code, this pattern allows you to require a JS and, than only when loading the JS is completed, load yet another dependency, but do so in the scope of the previously required file.
At large, this pattern allows you to break your app into multiple small JS files, and load them in an async way to speed up the loading process of web pages.
Some would argue that this is all going to be less needed when SPDY and HTTP2 are going to be more widely used. In any case, this is surely promotes a better modularity in the code design.

Asynchronous loading JavaScript functions.

I am building a framework in which I have merged all JavaScript files into one file (minify).
Example:
function A() {} function B() {}
Through minified file i want to load function asynchronous and remove from HTML when its work is done.
Example: load function A when it is required but not function B.
I have seen one framework Require.js but in that it loads JavaScript file asynchronous based on requirement.
Is there any framework which loads JavaScript functions on demand which are defined in same js file.
The downside to concatenation is you get less fine-grained control over what you are including on a given page load. The solution to this is, rather than creating one concatenated file, create layers of functionality that can be included a little more modularly. Thus you don't need all your JS on a page that may only use a few specific functions. This can actually be a win in speed as well, since having just one JS file might not take advantage of the browsers 6 concurrent connections. Moreover, once SPDY is fully adopted, one large file will actually be less performant than more smaller ones (since connections can be reused). Minification will still be important, however.
All that said, it seems you are asking for something a little difficult to pull off. When a browser loads a script, it gets parsed and executed immediately. You can't load the file then... only load part of the file. By concatenating, you are restricting yourself to that large payload.
It is possible to delay execution by wrapping a script in a block comment, then accessing it from the script node and eval()ing it... but that doesn't seem like what you are asking. It can be a useful strategy, though, if you want to preload modules without locking the UI.
That's not how javascript works. When the function's source file is loaded, the function is available in memory. Since the language is interpreted, the functions that are defined would be loaded as soon as the source file was read by the browser.
Your best bet is to use Require.js or something similar if you want to have explicit dependency chains.

pros and cons of javascript async loading vs jquery ajax(or getscript) async loading

I was reading this very interesting article for implementing async style loading of js on my site here http://css-tricks.com/thinking-async/.
My requirements are ability to load a javascript file in a async way and then call an initialization method from the file after it has successfully loaded. Which method is preferred way ie using the classic async way or using jQuery's getscript method as described in the above mentioned article? What are the merits or demerits of using one over the other?
EDIT: My take is: Lets say we are loading a js and then we want to call back an initialization function after successful load of the js file.This needs to happen as soon as possible because the whole module should be parsed and executed during page loading without waiting for document.ready or window.onload. Trying to do this via classic async way could lead to dealing with cross browser issues and rigourous testing, whereas if we use jquery ajax(or getscript method) we can avoid the hassles.
Also looking for this solution to load a single js file in a async way without using any library.
Edit: This answer is old, and apparently modern jQuery uses script injection
Loading javascript using the classic async way (which I'm assuming you mean with script injection or the async attribute in HTML 5) is very well accepted and is how most async loaders (including AMD, like RequireJS) implement it.
JQuery's getScript method is calling eval at the end of the day, which most decent JS developers tend to shy away from.
Snippet from jQuery source, currently line 613:
( window.execScript || function( data ) {
window[ "eval" ].call( window, data );
} )( data );
jQuery does pass in the window object as the context, saving some hassle and (likely, untested) fixing issues with things like eval's odd handling of garbage collection. There are also likely still issues with tracking lines during debugging, depending on your tool of choice.
I am a big proponent of the AMD method (using script injection), which allows asynchronously calling scripts right after their dependencies are loaded, and allows you to pass around modules between scripts rather than relying on the global namespace. You can get more information on AMD loading and async vs sync loading in general at the RequireJS site, or by checking out this relatively simple gist.

Categories

Resources