Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RequireJS : nested require calls

I have a scenario where I have nested require() calls to load up different modules.

Is there a way for me to ensure that all the require() invocation and all its child require() invocations are fully loaded before the callback function is called?

Is there a way to specify that require() calls are synchronous?

function someFunction(callback) {

  //top level require
  require([...], function(...) {

     //nested require
     require([...], function(...) {
     });

     //nested require
     require([...], function(...) {
     });

  });

  callback();
};
like image 815
glui2001 Avatar asked Jan 23 '13 19:01

glui2001


People also ask

How does RequireJS work?

RequireJS uses Asynchronous Module Loading (AMD) for loading files. Each dependent module will start loading through asynchronous requests in the given order. Even though the file order is considered, we cannot guarantee that the first file is loaded before the second file due to the asynchronous nature.

Why do we need RequireJS?

RequireJS is a basic loader, which is used to loads the JavaScript files, it is a framework to manage dependencies between JavaScript files, and in modular programming, all the functionality divides in different modules, so RequireJs is a best tool to assemble different JavaScript files from different modules by which ...

What is a RequireJS module?

RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.

What is define in RequireJS?

The define() function can be used to load the modules (module can be an object, function, class or a code which is executed after loading a module). You can load different versions of the same module in the same page.


2 Answers

You need to execute the callback in the last require(...) function:

function someFunction(callback) {
   require(['somemodule'], function(someModule) {
     // do stuff with someModule...

     // execute callback
     callback(); 
   });
}

What you also could do is to specify your dependencies with the define function.

Example:

define('somemodule', ['somedependency'], function(someDependency) {
   // return somemodule
   return {
     someProperty: someDependency.getProperty();
   };
});

function someFunction(callBack) {
   var someModule = require('somemodule');   
   var foo = someModule.someProperty;

   return callBack(foo);
}
like image 179
nekman Avatar answered Sep 23 '22 05:09

nekman


There is a way to make require call sync. Make it CommonJS style:

var module = require('modulepath')

So, if you would NOT need a factory funciton in your nested require calls, you could "sync" the require calls that way... But since you do you are out of luck.

AMD style requre(depsArray, factoryFn) is exactly like pushing your code into a parallel thread. There is no way to make it "sync" but you can use "semaphores" to coordinate the result.

The answer to your question also greatly depends on what nested A and nested B consume. If they depend on some product from top require like so you absolutely must use "threaded semaphores" and cannot just push nested require calls into named define calls:

function someFunction(callback) {

  var resultOfOuterCode = someResultOfCalculations

  //top level require
  require([...], function(...) {

    var resultOfTopRequireCode = someOtherResultOfCalculations

    var semaphore = {
      'count': 2 // represents the number of thread that need to be "done" before 
      , 'callback':callback // this callback is fired.
      , 'checkIfLast': function(){
        this.count -= 1
        if (!this.count) {
          // count is now 0 - time to run our callback
          this.callback()
        }
      }
    }

    //nested require A
    require([...], function(...) {
      // using resultOfTopRequireCode // <-- !!!! this is important part
      ...
      semaphore.checkIfLast()
    });

    //nested require B
    require([...], function(...) {
      // using resultOfTopRequireCode // <-- !!!! this is important part
      semaphore.checkIfLast()
    });

  });

};

In other words, just think of require(dependsArray, factoryFn) as "threads" and apply your understanding of using threads to it.

like image 27
ddotsenko Avatar answered Sep 25 '22 05:09

ddotsenko