UIZE JavaScript Framework

2012 NEWS 2012-09-03 - Improved Module Mechanism

The module mechanism of the UIZE JavaScript Framework has been improved with the addition of support for parallel ascynchronous loading of required modules and the new Uize.require static method.

1. Parallel Ascynchronous Loading of Required Modules

The module mechanism, implemented in the Uize base module, has been improved with the addition of support for parallel asynchronous loading of required modules.

Whereas previously, modules required as direct dependencies for a module would be loaded asynchronously in a non-blocking fashion but in a one after another sequence, now required modules are loaded in parallel. This new approach takes full advantage of the ability of most modern browsers to open several simultaneous connections for loading in multiple external JavaScript files in parallel, asynchronously, and in no guaranteed order (using the async attribute of the script tag). Not to worry, the module mechanism still ensures that a module is only built once all its required modules are loaded, regardless of in which order those direct dependencies are loaded and built.

The effect of this change is to speed up loading of individual JavaScript modules (i.e. when library modules are not being used).

2. The New Uize.require Static Method

The new Uize.require static method, implemented in the Uize base module, ensures that all of the specified modules are loaded before calling the specified callback function, loading required modules as necessary.

The Uize.require method can be used to load required modules, as necessary, before executing code that depends on those modules being loaded.

DIFFERENT USAGES

Require a Single Module

Uize.require (moduleNameSTR,callbackFUNC);

Require Multiple Modules

Uize.require (moduleNamesARRAY,callbackFUNC);

Require Modules With No Callback

Uize.require (moduleNameSTRorModuleNamesARRAY);

2.1. Require a Single Module

In the most basic usage, a single module can be required by specifying the name of the module as a string for the moduleNameSTR parameter.

SYNTAX

Uize.require (moduleNameSTR,callbackFUNC);

EXAMPLE 1

Uize.require (
  'Uize.Widget.Bar.Slider',
  function (Slider) {
    var mySlider = Slider ({
      minValue:-50,
      maxValue:50,
      value:0
    });
  }
);

In the above example, the Uize.Widget.Bar.Slider widget class module is being required. Once the Uize.Widget.Bar.Slider module is loaded, the Uize.require method will call the callback specified by the callbackFUNC parameter, passing a reference to Uize.Widget.Bar.Slider module as the callback function's first argument. In this example, we have named the argument Slider. You can name this argument anything you like, as long as it's a valid JavaScript identifier. If we wanted to reinforce that this argument is a reference to the Uize.Widget.Bar.Slider module, we could name the argument something like Uize_Widget_Bar_Slider or UizeWidgetBarSlider (depending on whether or not we like using underscores in variable names).

EXAMPLE 2

Uize.require (
  'Uize.Widget.Bar.Slider',
  function () {
    var mySlider = Uize.Widget.Bar.Slider ({
      minValue:-50,
      maxValue:50,
      value:0
    });
  }
);

In the above example, we are also requiring the Uize.Widget.Bar.Slider module. In this case, however, instead of using the reference to the module that would be passed to the callback function, we are simply ignoring this argument and referencing the Uize.Widget.Bar.Slider module by its name in the global scope. This is also supported.

2.2. Require Multiple Modules

In cases where you need to require more than one module, a list of module names can be specified as a string array for the moduleNamesARRAY parameter.

SYNTAX

Uize.require (moduleNamesARRAY,callbackFUNC);

EXAMPLE

Uize.require (
  [
    'Uize.Widget.Bar.Slider',
    'Uize.Data.Csv',
    'Uize.Color'
  ],
  function (
    Uize_Widget_Bar_Slider,
    Uize_Data_Csv,
    Uize_Color
  ) {
    // reference the Uize.Widget.Bar.Slider module by Uize_Widget_Bar_Slider
    // reference the Uize.Data.Csv module by Uize_Data_Csv
    // reference the Uize.Color module by Uize_Color
  }
);

In the above example, the three modules Uize.Widget.Bar.Slider, Uize.Data.Csv, and Uize.Color are being required. Once all of these modules are loaded, references to the modules are passed as arguments to the callback function, in the order in which the modules are specified in the moduleNamesARRAY parameter. The arguments can be named anything you like, but it helps to name them so as to clearly indicate the modules to which they are references. As with the using the Uize.require method to require a single module, the module references that would be passed as arguments to the callback function can simply be ignored in favor of referencing the modules using their names in the global scope.

2.3. Require Modules With No Callback

In an uncommon usage, one or more modules can be required without specifying any callback function to be called once the modules are loaded.

SYNTAX

Uize.require (moduleNameSTRorModuleNamesARRAY);

With this usage, the Uize.require method can be used simply to initiate loading of modules.

EXAMPLE

Uize.require ([
  'Uize.Widget.Bar.Slider',
  'Uize.Data.Csv',
  'Uize.Color'
]);

In the above example, the three modules Uize.Widget.Bar.Slider, Uize.Data.Csv, and Uize.Color are being required without specifying any code that should be executed once the modules are loaded.

2.4. The callbackFUNC Parameter

The callbackFUNC parameter of the Uize.require method lets you specify a callback function that should be executed once all the required modules are loaded.

When the Uize.require method calls the specified callback function, it passes references to the required modules as arguments, in the order in which the modules are specified in the first parameter of the Uize.require method. Consider the following example...

EXAMPLE

Uize.require (
  [
    'MyNamespace.MyModule1',
    'MyNamespace.MyModule2'
  ],
  function (
    MyNamespace_MyModule1,
    MyNamespace_MyModule2
  ) {
    // reference the MyNamespace.MyModule1 module by MyNamespace_MyModule1
    // reference the MyNamespace.MyModule2 module by MyNamespace_MyModule2
  }
);

In the above example, the modules MyNamespace.MyModule1 and MyNamespace.MyModule2 are being required. Once these modules are loaded, references to the modules are passed as arguments to the callback function. The arguments can be named anything you like, but it helps to name them so as to clearly indicate the modules to which they are references. Here, for example, we have chosen to name the first argument MyNamespace_MyModule1, since it will be a reference to the MyNamespace.MyModule1 module.

2.5. Requiring Nothing

In cases where one specifies an empty array for the moduleNamesARRAY parameter, the callback function specified by the callbackFUNC parameter will be executed immediately, and the callback will receive no arguments.

EXAMPLE

Uize.require (
  [],
  function () {
    // code here is executed immediately, because no modules need to be loaded
  }
);

One would not deliberately write code as shown in the above example, but situations like this may arise where a list of modules that is to be required is being determined programmatically, and where in some situations a programmatically determined list may be empty. Rather than having to implement a check for such cases along with appropriate protection / conditional branching, the Uize.require method does the logical thing and calls the specified callback function immediately, since all requirements (none, in this case) are already satisfied. An empty list indicates that the callback code is not contingent upon anything, so it is executed straight away.

2.6. Equivalent to Anonymous Modules

While more concise and convenient, the Uize.require method is roughly equivalent to using anonymous modules.

INSTEAD OF...

Uize.module ({
  required:[
    'MyNamespace.MyModule1',
    'MyNamespace.MyModule2'
  ],
  builder:function () {
    // code here can rely on MyNamespace.MyModule1 and MyNamespace.MyModule2 being loaded
  }
});

USE...

Uize.require (
  [
    'MyNamespace.MyModule1',
    'MyNamespace.MyModule2'
  ],
  function () {
    // code here can rely on MyNamespace.MyModule1 and MyNamespace.MyModule2 being loaded
  }
);

In addition to being a little bit cleaner and more concise, as well as a bit more semantically elegant, the Uize.require method also supports passing references to required modules in the callbackFUNC parameter.