How to load chained scripts recursively with javascript?

1

Hello everyone. I'm trying to make a function that works like require of some languages, like Ruby. Using% w /% after the page is already loaded is smooth, but chaining and loading time is a tricky task.

With createElement javascript does not load, it emits a document.write("<script src=" + ...) stating that it can not be used when scripts are loading asynchronously.

The complexity of my case is due to the fact that a script depends on another one that is in another file, and this, in turn, depends on another one, which is also in another file (chain request). I could solve everything by making a big file, but, I'm very methodical with organization, and I feel very bad when I'm going to keep something in a huge file. Give it warning .

I do not like having to use plugins for everything to do, so I eliminate dependencies (the more dependency, less knowledge, and less control of what goes on behind the curtains), among other things. The ctrl + f is functional, but it uses callback to do AMD (Asynchronous Module Definition) , generating semantic strangeness. >

also uses callback . The requirejs method does XHR to get the script on the server, the callback being sure to load, which is not my pretension either. What I intend to do, is an alternative more similar to the conventional form of other languages. I do not know if it is possible, but suddenly recursively use .getScript to not allow lines after require to be interpreted, otherwise an error will be thrown because the file on which the script depends it would still not be fully loaded, and there is not yet setTimeout to be extended.

More complex is still to do this in a chain, since the last file added must be the first to be loaded, then the next to last, and so on, until the subsequent lines of the first file, which triggers this chain reaction , continue to be interpreted. In case no error would be raised, because nothing would be given as Objeto .

    
asked by anonymous 12.12.2015 / 02:01

1 answer

1

Rafael, doing this kind of management can be a bit tricky, maybe we'll let some situation go by, etc.

In any case it follows a small implementation:

//o primeiro argumento deveria ser a url do script, mas para este exemplo irei utilizar uma URL dinamica.
var Script = function (name, callback) {
  var self = this;
  self.name = name;
  self.callbacks = [];
  if (callback) {
    self.callbacks.push(callback);
  }

  // criando uma URL dinamica apartir do template
  self.source = document.getElementById(self.name).innerHTML;
  self.blob = new Blob([self.source], { type: "text/javascript" });
  self.url = URL.createObjectURL(self.blob);

  self.elem = document.createElement("script");
  self.elem.src = self.url;  
  self.elem.addEventListener("load", function () {
    self.callbacks.forEach(function (callback, indice) {
      callback(self);
    });
  });
  document.head.appendChild(self.elem);
}

Script.all = function(scripts, callback) {
  if (callback) {
    var complete = 0;
    var total = scripts.length;
    for (var indice = 0; indice < total; indice++) {
      scripts[indice].callbacks.push(function () {
        complete++;
        if (complete == total) {
          callback();
        }
      });
    }
  }
}

var then = function (script) { 
  console.log(script.name + " carregado"); 
};

var scripts = [];
scripts.push(new Script("script1", then));
scripts.push(new Script("script2", null));
scripts.push(new Script("script3", then));

Script.all(scripts, function () {
  console.log("scripts 1, 2 e 3 carregados");
  new Script("script4", then);
});
<template id="script1">
  console.log("script1");
</template>
<template id="script2">
  console.log("script2");
</template>
<template id="script3">
  console.log("script3");
</template>
<template id="script4">
  console.log("script4");
</template>

In the example above, I get a notification when script1 and / or script3 are ready, regardless of the situation of the other scripts ...

When script1 , script2 and script3 are ready, then I add script4 ... that is, script4 depends on script1 , script2 e the script3 .

    
24.02.2016 / 15:37