title: Javascript - Delaying module return/declaration in Require.js?
body: <p>I have a module that returns an array comprised of JSON data and image objects.  Since both loading the JSON (from other files) and the image objects takes time, I need my module to only return the array once both are completed.</p>
  
  <p>Currently, the module is always returning 'undefined' in other modules, and I believe it is because the module is not waiting to return like I expect it to (but I'm not sure).  Or, because the other module using this Atlas module is declaring it as a variable before it has returned anything.</p>
  
  <p><em>Editted to show how I am defining/requiring modules</em>
  *Editted again to show more code*</p>
  
  <p><a href="http://farmmonsters.com/level-editor/">The live code can be seen here</a>.</p>
  
  <p>Here is my tile-atlas module:</p>
  
  <pre><code>define( function() {
  
  var tilesheetPaths = [
              "tilesheets/ground.json",
      "tilesheets/ground-collision.json",
      "tilesheets/objects-collision.json"
  ];
  
  var tileAtlas = [ ];
  
  
  function loadAtlasJSON() {  
      for (var i = 0; i &lt; tilesheetPaths.length; i++) {
          loadJSON( 
              {
                  fileName: tilesheetPaths[ i ],
                  success: function( atlas ) {            
                      addToTileAtlas( atlas );
                  }
              } 
          );
      }
  };
  
  
  function addToTileAtlas( atlas ) {
      atlas.loaded = false;
      var img = new Image();
  
      img.onload = function() {
          atlas.loaded = true;
      };
  
      img.src = atlas.src;
  
      // Store the image object as an "object" property
      atlas.object = img;
      tileAtlas[ atlas.id ] = atlas;
  }
  
  
  // Returns tileAtlas[ ] once everything is loaded and ready
  function tileAtlasReady() {
      if ( allJSONloaded() &amp;&amp; allImagesLoaded() ) {
          console.log("TileAtlas ready"); 
          return tileAtlas;
      }
      console.log("TileAtlas not ready");
      setTimeout(tileAtlasReady, 10);
  };
  
  
  // Checks to make sure all XMLHttpRequests are finished and response is added to tileAtlas
  function allJSONloaded() {
      // If the tilesheet count in tileAtlas !== the total amount of tilesheets
      if ( Object.size(tileAtlas) !== tilesheetPaths.length ) {
          // All tilesheets have not been loaded into tileAtlas
          console.log("JSON still loading");
          return false;
      } 
      console.log("All JSON loaded");
      return true;
  };
  
  
  // Checks that all img objects have been loaded for the tilesheets
  function allImagesLoaded() {
      for ( var tilesheet in tileAtlas ) {
          if (tileAtlas[tilesheet].loaded !== true) {
              console.log("Images still loading");
              return false;
          }
      }
      console.log("All images loaded");
      return true;
  };
  
  
  // Loads the JSON/images
  loadAtlasJSON();
  
  // Module should only return when tileAtlasReady() returns
  return tileAtlasReady();
  
  } );
  </code></pre>
  
  <p>And this is my loadJSON function from my lib:</p>
  
  <pre><code>window.loadJSON = function( args ) {
      var xhr = new XMLHttpRequest();
      xhr.overrideMimeType( "application/json" );
      xhr.open( "GET", args.fileName, true );
  
      xhr.onreadystatechange = function () {
          if ( xhr.readyState == 4 ) {        
  
              if ( xhr.status == "200" ) {
                  // Check that response is valid JSON
                  try {
                      JSON.parse( xhr.responseText );
                  } catch ( e ) {
                      console.log( args.fileName + ": " + e );
                      return false;
                  }
                  args.success( JSON.parse(xhr.responseText) );
              // xhr.status === "404", file not found
              } else {
                  console.log("File: " + args.fileName + " was not found!");
              }
          }
      }
      xhr.send();
  }   
  </code></pre>
  
  <p>And the module loading my tile-atlas module:</p>
  
  <pre><code>define( ['data/tile-atlas'], function( tileAtlas ) {
  
  function displayImages() {
      // Code
  };
  
  // Returns undefined
  console.log(tileAtlas);
  
  displayKey();
  
  } );
  </code></pre>
  
  <p>And here is what the output looks like:</p>
  
  <pre><code>[12:14:45.407] "JSON still loading"
  [12:14:45.407] "TileAtlas not ready"
  [12:14:45.408] undefined 
  
  [12:14:45.428] "JSON still loading"
  [12:14:45.428] "TileAtlas not ready"
  
  [12:14:45.469] "All JSON loaded"
  [12:14:45.470] "Images still loading"
  [12:14:45.470] "TileAtlas not ready"
  
  [12:14:45.481] "All JSON loaded"
  [12:14:45.481] "Images still loading"
  [12:14:45.481] "TileAtlas not ready"
  
  [12:14:45.492] "All JSON loaded"
  [12:14:45.492] "All images loaded"
  [12:14:45.492] "TileAtlas ready"
  </code></pre>
  
  <p>The 'undefined' is from when I console.log my Atlas module from a different module, that depends on the Atlas module.</p>
  
  <p>I'm not sure if it is the Atlas module returning something before it should, or the other modules declaring the Atlas module as a variable before it has returned something.</p>
  
  <p>But if it is the latter, is there a way to make it so that modules will not run until their dependencies are finished returning something?</p>
  
  <p>I am completely new to Require.js and AMD: Is this approach inherently flawed?  I would think that using AMD with loading-sensitive modules is common.</p>
  
  <p>Thanks for your help.</p>
  
  <p><em><strong>EDIT</em>  Looking at the source code of another game, I realized that I can just load my jSON files with the require.js text plugin, instead of implementing an XHR in my module.  This is much simpler, as I won't need to deal with the complexity of waiting for XHRs within a module.
  <a href="https://github.com/mozilla/BrowserQuest/blob/master/client/js/sprites.js">Here is how BrowserQuest does so</a>.</strong></p>