Dynamically loading JavaScript synchronously









up vote
53
down vote

favorite
16












I'm using the module pattern, one of the things I want to do is dynamically include an external JavaScript file, execute the file, and then use the functions/variables in the file in the return of my module.



I can't figure out how to do this easily. Are there any standard ways of performing a pseudo synchronous external script load?



function myModule() 
var tag = document.createElement("script");
tag.type = "text/javascript";
tag.src = "http://some/script.js";
document.getElementsByTagName('head')[0].appendChild(tag);

//something should go here to ensure file is loaded before return is executed

return
external: externalVariable











share|improve this question

















  • 3




    So you want to interrupt client operation completely while you load a file from a remote server?
    – Pointy
    May 21 '10 at 4:11






  • 1




    Not necessarily, I just want to know how to not return on myModule until a resource is available... or how to ensure some external variable is available before my module is executed.
    – Eric Schoonover
    May 21 '10 at 4:24







  • 3




    RE: Pointy's comment about interrupting client operation while loading a file from a remote server, ... isn't this how things work already in certain browsers, when you have <script> tags one after the other in the head of the document?
    – Funka
    Apr 13 '11 at 23:45






  • 7




    @Pointy Regarding your snarky comment: my own use case for this currently is client-side search from file:///. I don't want to load megabytes of JSON until I know that the user needs the 5-word phrase file, but once I know that it's needed I need to load it ASAP and need to wait until it is loaded before I can perform the search. So: yes, I want to interrupt client operation completely while the code necessary to complete the search results happens. :p
    – Phrogz
    Jun 20 '12 at 15:52







  • 1




    @Pointy Well, I don't need the UI to freeze, that's true. However, the use case is that the user is typing/has typed in a search term and I need to find the results, and I need to load additional JS files to do so. There is essentially no latency from the disk, and the browser is going to stutter for a second while the megabytes of JS are loaded anyhow, and the moment they are loaded I need to use them..so synchronous (if possible) would have been "good enough" for my case, and a hair simpler than the solution I came up with below.
    – Phrogz
    Jun 20 '12 at 16:20















up vote
53
down vote

favorite
16












I'm using the module pattern, one of the things I want to do is dynamically include an external JavaScript file, execute the file, and then use the functions/variables in the file in the return of my module.



I can't figure out how to do this easily. Are there any standard ways of performing a pseudo synchronous external script load?



function myModule() 
var tag = document.createElement("script");
tag.type = "text/javascript";
tag.src = "http://some/script.js";
document.getElementsByTagName('head')[0].appendChild(tag);

//something should go here to ensure file is loaded before return is executed

return
external: externalVariable











share|improve this question

















  • 3




    So you want to interrupt client operation completely while you load a file from a remote server?
    – Pointy
    May 21 '10 at 4:11






  • 1




    Not necessarily, I just want to know how to not return on myModule until a resource is available... or how to ensure some external variable is available before my module is executed.
    – Eric Schoonover
    May 21 '10 at 4:24







  • 3




    RE: Pointy's comment about interrupting client operation while loading a file from a remote server, ... isn't this how things work already in certain browsers, when you have <script> tags one after the other in the head of the document?
    – Funka
    Apr 13 '11 at 23:45






  • 7




    @Pointy Regarding your snarky comment: my own use case for this currently is client-side search from file:///. I don't want to load megabytes of JSON until I know that the user needs the 5-word phrase file, but once I know that it's needed I need to load it ASAP and need to wait until it is loaded before I can perform the search. So: yes, I want to interrupt client operation completely while the code necessary to complete the search results happens. :p
    – Phrogz
    Jun 20 '12 at 15:52







  • 1




    @Pointy Well, I don't need the UI to freeze, that's true. However, the use case is that the user is typing/has typed in a search term and I need to find the results, and I need to load additional JS files to do so. There is essentially no latency from the disk, and the browser is going to stutter for a second while the megabytes of JS are loaded anyhow, and the moment they are loaded I need to use them..so synchronous (if possible) would have been "good enough" for my case, and a hair simpler than the solution I came up with below.
    – Phrogz
    Jun 20 '12 at 16:20













up vote
53
down vote

favorite
16









up vote
53
down vote

favorite
16






16





I'm using the module pattern, one of the things I want to do is dynamically include an external JavaScript file, execute the file, and then use the functions/variables in the file in the return of my module.



I can't figure out how to do this easily. Are there any standard ways of performing a pseudo synchronous external script load?



function myModule() 
var tag = document.createElement("script");
tag.type = "text/javascript";
tag.src = "http://some/script.js";
document.getElementsByTagName('head')[0].appendChild(tag);

//something should go here to ensure file is loaded before return is executed

return
external: externalVariable











share|improve this question













I'm using the module pattern, one of the things I want to do is dynamically include an external JavaScript file, execute the file, and then use the functions/variables in the file in the return of my module.



I can't figure out how to do this easily. Are there any standard ways of performing a pseudo synchronous external script load?



function myModule() 
var tag = document.createElement("script");
tag.type = "text/javascript";
tag.src = "http://some/script.js";
document.getElementsByTagName('head')[0].appendChild(tag);

//something should go here to ensure file is loaded before return is executed

return
external: externalVariable








javascript






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked May 21 '10 at 4:10









Eric Schoonover

27.4k38140189




27.4k38140189







  • 3




    So you want to interrupt client operation completely while you load a file from a remote server?
    – Pointy
    May 21 '10 at 4:11






  • 1




    Not necessarily, I just want to know how to not return on myModule until a resource is available... or how to ensure some external variable is available before my module is executed.
    – Eric Schoonover
    May 21 '10 at 4:24







  • 3




    RE: Pointy's comment about interrupting client operation while loading a file from a remote server, ... isn't this how things work already in certain browsers, when you have <script> tags one after the other in the head of the document?
    – Funka
    Apr 13 '11 at 23:45






  • 7




    @Pointy Regarding your snarky comment: my own use case for this currently is client-side search from file:///. I don't want to load megabytes of JSON until I know that the user needs the 5-word phrase file, but once I know that it's needed I need to load it ASAP and need to wait until it is loaded before I can perform the search. So: yes, I want to interrupt client operation completely while the code necessary to complete the search results happens. :p
    – Phrogz
    Jun 20 '12 at 15:52







  • 1




    @Pointy Well, I don't need the UI to freeze, that's true. However, the use case is that the user is typing/has typed in a search term and I need to find the results, and I need to load additional JS files to do so. There is essentially no latency from the disk, and the browser is going to stutter for a second while the megabytes of JS are loaded anyhow, and the moment they are loaded I need to use them..so synchronous (if possible) would have been "good enough" for my case, and a hair simpler than the solution I came up with below.
    – Phrogz
    Jun 20 '12 at 16:20













  • 3




    So you want to interrupt client operation completely while you load a file from a remote server?
    – Pointy
    May 21 '10 at 4:11






  • 1




    Not necessarily, I just want to know how to not return on myModule until a resource is available... or how to ensure some external variable is available before my module is executed.
    – Eric Schoonover
    May 21 '10 at 4:24







  • 3




    RE: Pointy's comment about interrupting client operation while loading a file from a remote server, ... isn't this how things work already in certain browsers, when you have <script> tags one after the other in the head of the document?
    – Funka
    Apr 13 '11 at 23:45






  • 7




    @Pointy Regarding your snarky comment: my own use case for this currently is client-side search from file:///. I don't want to load megabytes of JSON until I know that the user needs the 5-word phrase file, but once I know that it's needed I need to load it ASAP and need to wait until it is loaded before I can perform the search. So: yes, I want to interrupt client operation completely while the code necessary to complete the search results happens. :p
    – Phrogz
    Jun 20 '12 at 15:52







  • 1




    @Pointy Well, I don't need the UI to freeze, that's true. However, the use case is that the user is typing/has typed in a search term and I need to find the results, and I need to load additional JS files to do so. There is essentially no latency from the disk, and the browser is going to stutter for a second while the megabytes of JS are loaded anyhow, and the moment they are loaded I need to use them..so synchronous (if possible) would have been "good enough" for my case, and a hair simpler than the solution I came up with below.
    – Phrogz
    Jun 20 '12 at 16:20








3




3




So you want to interrupt client operation completely while you load a file from a remote server?
– Pointy
May 21 '10 at 4:11




So you want to interrupt client operation completely while you load a file from a remote server?
– Pointy
May 21 '10 at 4:11




1




1




Not necessarily, I just want to know how to not return on myModule until a resource is available... or how to ensure some external variable is available before my module is executed.
– Eric Schoonover
May 21 '10 at 4:24





Not necessarily, I just want to know how to not return on myModule until a resource is available... or how to ensure some external variable is available before my module is executed.
– Eric Schoonover
May 21 '10 at 4:24





3




3




RE: Pointy's comment about interrupting client operation while loading a file from a remote server, ... isn't this how things work already in certain browsers, when you have <script> tags one after the other in the head of the document?
– Funka
Apr 13 '11 at 23:45




RE: Pointy's comment about interrupting client operation while loading a file from a remote server, ... isn't this how things work already in certain browsers, when you have <script> tags one after the other in the head of the document?
– Funka
Apr 13 '11 at 23:45




7




7




@Pointy Regarding your snarky comment: my own use case for this currently is client-side search from file:///. I don't want to load megabytes of JSON until I know that the user needs the 5-word phrase file, but once I know that it's needed I need to load it ASAP and need to wait until it is loaded before I can perform the search. So: yes, I want to interrupt client operation completely while the code necessary to complete the search results happens. :p
– Phrogz
Jun 20 '12 at 15:52





@Pointy Regarding your snarky comment: my own use case for this currently is client-side search from file:///. I don't want to load megabytes of JSON until I know that the user needs the 5-word phrase file, but once I know that it's needed I need to load it ASAP and need to wait until it is loaded before I can perform the search. So: yes, I want to interrupt client operation completely while the code necessary to complete the search results happens. :p
– Phrogz
Jun 20 '12 at 15:52





1




1




@Pointy Well, I don't need the UI to freeze, that's true. However, the use case is that the user is typing/has typed in a search term and I need to find the results, and I need to load additional JS files to do so. There is essentially no latency from the disk, and the browser is going to stutter for a second while the megabytes of JS are loaded anyhow, and the moment they are loaded I need to use them..so synchronous (if possible) would have been "good enough" for my case, and a hair simpler than the solution I came up with below.
– Phrogz
Jun 20 '12 at 16:20





@Pointy Well, I don't need the UI to freeze, that's true. However, the use case is that the user is typing/has typed in a search term and I need to find the results, and I need to load additional JS files to do so. There is essentially no latency from the disk, and the browser is going to stutter for a second while the megabytes of JS are loaded anyhow, and the moment they are loaded I need to use them..so synchronous (if possible) would have been "good enough" for my case, and a hair simpler than the solution I came up with below.
– Phrogz
Jun 20 '12 at 16:20













16 Answers
16






active

oldest

votes

















up vote
51
down vote



accepted










There is only one way to synchronously load and execute a script resource, and that is using a synchronous XHR



This is an example of how to do this



// get some kind of XMLHttpRequest
var xhrObj = createXMLHTTPObject();
// open and send a synchronous request
xhrObj.open('GET', "script.js", false);
xhrObj.send('');
// add the returned content to a newly created script tag
var se = document.createElement('script');
se.type = "text/javascript";
se.text = xhrObj.responseText;
document.getElementsByTagName('head')[0].appendChild(se);


But you shouldn't in general use synchronous requests as this will block everything else.
But that being said, there are of course scenarios where this is appropriate.



I would probably refactor the containing function into an asynchronous pattern though using an onload handler.






share|improve this answer


















  • 1




    I ended up refactoring so that onload/onreadystate change would work. But this is the correct answer to my original question.
    – Eric Schoonover
    May 21 '10 at 7:27






  • 7




    Note that this will not work for the (admittedly edge case) of trying to load JS synchronously from file:// on browsers like Chrome where XHR over file:// is prohibited.
    – Phrogz
    Jun 20 '12 at 15:54






  • 2




    Looks like this fails cross-domain. Is there a way to do dynamic synch injection of 3rd party scripts? Tia.
    – Steven Francolla
    Feb 14 '13 at 4:01






  • 1




    Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help xhr.spec.whatwg.org
    – WebolizeR
    Jan 15 '15 at 11:26






  • 2




    This does not wait for the script to be executed synchronously.
    – Flimm
    Jul 11 '17 at 10:36

















up vote
34
down vote













The accepted answer is NOT correct.



Loading a file synchronously is not the same as executing the file synchronously - which is what the OP requested.



The accepted answer loads the file sync, but does nothing more than append a script tag to the DOM. Just because appendChild() has returned does not in anyway guarantee that the script has finished executing and it's members are initialised for use.



The only (see caveat) way to achieve the OPs question is to sync load the script over XHR as stated, then read as text and pass into either eval() or a new Function() call and wait for that function to return. This is the only way to guarantee the script is loaded AND executed synchronously.



I make no comment as to whether this is a wise thing to do either from a UI or security perspective, but there are certainly use cases that justify a sync load & execute.



Caveat:
Unless you're using web workers in which case just call loadScripts();






share|improve this answer





























    up vote
    9
    down vote













    This is the code that I'm using for multiple file load in my app.



    Utilities.require = function (file, callback) 
    callback = callback ;

    Utilities.requireFiles = function ()
    var index = 0;
    return function (files, callback)
    index += 1;
    Utilities.require(files[index - 1], callBackCounter);

    function callBackCounter()
    if (index === files.length)
    index = 0;
    callback();
    else
    Utilities.requireFiles(files, callback);

    ;
    ;
    ();


    And this utilities can be used by



    Utilities.requireFiles(["url1", "url2",....], function()
    //Call the init function in the loaded file.
    )





    share|improve this answer
















    • 1




      Does that work for nested items aswell? Say if you require more files inside the files you require?
      – Johan
      Nov 16 '12 at 12:18






    • 4




      This is async, not syncronues!
      – momo
      Jul 13 '13 at 10:18






    • 2




      the callback function is called upon the specified scripts are loaded. Isn't it good enough?
      – Kenji Noguchi
      Jan 27 '14 at 0:45










    • async is not sync. does not answer OP.
      – catbadger
      Jun 23 '17 at 14:37

















    up vote
    5
    down vote













    The most Node.js-like implementation I could come up with was able to load JS files synchonously, and use them as objects/modules



    var scriptCache = ;
    var paths = ;
    function Import(path)

    var index = 0;
    if((index = paths.indexOf(path)) != -1) //If we already imported this module

    return scriptCache [index];


    var request, script, source;
    var fullPath = window.location.protocol + '//' + window.location.host + '/' + path;

    request = new XMLHttpRequest();
    request.open('GET', fullPath, false);
    request.send();

    source = request.responseText;

    var module = (function concealedEval()
    eval(source);
    return exports;
    )();

    scriptCache.push(module);
    paths.push(path);

    return module;



    An example source (addobjects.js):



    function AddTwoObjects(a, b)

    return a + b;


    this.exports = AddTwoObjects;


    And use it like this:



    var AddTwoObjects = Import('addobjects.js');
    alert(AddTwoObjects(3, 4)); //7
    //or even like this:
    alert(Import('addobjects.js')(3, 4)); //7





    share|improve this answer





























      up vote
      3
      down vote













      I had the following problem(s) with the existing answers to this question (and variations of this question on other stackoverflow threads):



      • None of the loaded code was debuggable

      • Many of the solutions required callbacks to know when loading was finished instead of truly blocking, meaning I would get execution errors from immediately calling loaded (ie loading) code.

      Or, slightly more accurately:



      • None of the loaded code was debuggable (except from the HTML script tag block, if and only if the solution added a script elements to the dom, and never ever as individual viewable scripts.) => Given how many scripts I have to load (and debug), this was unacceptable.

      • Solutions using 'onreadystatechange' or 'onload' events failed to block, which was a big problem since the code originally loaded dynamic scripts synchronously using 'require([filename, 'dojo/domReady']);' and I was stripping out dojo.

      My final solution, which loads the script before returning, AND has all scripts properly accessible in the debugger (for Chrome at least) is as follows:



      WARNING: The following code should PROBABLY be used only in 'development' mode. (For 'release' mode I recommend prepackaging and minification WITHOUT dynamic script loading, or at least without eval).



      //Code User TODO: you must create and set your own 'noEval' variable

      require = function require(inFileName)

      var aRequest
      ,aScript
      ,aScriptSource
      ;

      //setup the full relative filename
      inFileName =
      window.location.protocol + '//'
      + window.location.host + '/'
      + inFileName;

      //synchronously get the code
      aRequest = new XMLHttpRequest();
      aRequest.open('GET', inFileName, false);
      aRequest.send();

      //set the returned script text while adding special comment to auto include in debugger source listing:
      aScriptSource = aRequest.responseText + 'n////# sourceURL=' + inFileName + 'n';

      if(noEval)//<== **TODO: Provide + set condition variable yourself!!!!**

      //create a dom element to hold the code
      aScript = document.createElement('script');
      aScript.type = 'text/javascript';

      //set the script tag text, including the debugger id at the end!!
      aScript.text = aScriptSource;

      //append the code to the dom
      document.getElementsByTagName('body')[0].appendChild(aScript);

      else

      eval(aScriptSource);

      ;





      share|improve this answer



























        up vote
        2
        down vote













        var xhrObj = new XMLHttpRequest();
        xhrObj.open('GET', '/filename.js', false);
        xhrObj.send(null);
        eval(xhrObj.responseText);


        If this is a cross-domain request, it will not work. In that case you have to upload the requested file to your server, or make a mirror php that outputs it, and require that php.



        With jquery (works with cross-domain request too):



        $.getScript('/filename.js',callbackFunction);


        callbackFunction will be called synchronously.



        For loading more scripts see this thread.






        share|improve this answer





























          up vote
          1
          down vote













          If you need to load an arbitrary number of scripts and only proceed when the last one is done, and you cannot use XHR (e.g. due to CORS limitations) you can do the following. It is not synchronous, but does allow a callback to occur exactly when the last file is done loading:



          // Load <script> elements for all uris
          // Invoke the whenDone callback function after the last URI has loaded
          function loadScripts(uris,whenDone)
          if (!uris.length) whenDone && whenDone();
          else
          for (var wait=,i=uris.length;i--;)
          var tag = document.createElement('script');
          tag.type = 'text/javascript';
          tag.src = uris[i];
          if (whenDone)
          wait.push(tag)
          tag.onload = maybeDone;
          tag.onreadystatechange = maybeDone; // For IE8-

          document.body.appendChild(tag);


          function maybeDone() this.readyState==='complete')
          // Pull the tags out based on the actual element in case IE ever
          // intermingles the onload and onreadystatechange handlers for the same
          // script block before notifying for another one.
          for (var i=wait.length;i--;) if (wait[i]==this) wait.splice(i,1);
          if (!wait.length) whenDone();





          Edit: Updated to work with IE7, IE8, and IE9 (in quirks mode). These IE versions do not fire an onload event, but do for onreadystatechange. IE9 in standards mode fires both (with onreadystatechange for all scripts firing before onload for any).



          Based on this page there may be a small chance that old versions of IE will never send an onreadystatechange event with readyState=='complete'; if this is the case (I could not reproduce this problem) then the above script will fail and your callback will never be invoked.






          share|improve this answer






















          • I think there may be some per-browser issues with getting the "load" event reliably (or at all), based on various grumblings I've seen from script loader authors.
            – Pointy
            Jun 20 '12 at 16:14










          • @Pointy Ooh, that's good to know; thanks. I'll have to look into that more.
            – Phrogz
            Jun 20 '12 at 16:16






          • 1




            I'm not very familiar with the issues; I've been looking through the source of LABjs and mostly it's just making me confused. (I picked that one because the author is an acquaintance.)
            – Pointy
            Jun 20 '12 at 16:26










          • @Pointy Thanks to your note I found this page which describes the need to use onreadystatechange for IE. In testing, IE9 in standards mode does not require this, but older versions do. I've updated my answer with code that works in the current versions of all major browsers, and also IE7 and IE8.
            – Phrogz
            Jun 20 '12 at 19:42


















          up vote
          0
          down vote













          You can't and shouldn't perform server operations synchronously for obvious reasons. What you can do, though, is to have an event handler telling you when the script is loaded:



          tag.onreadystatechange = function() if (this.readyState == 'complete' ;

          tag.onload = function(load) /*init code here*/


          onreadystatechange delegation is, from memory, a workaround for IE, which has patchy support for onload.






          share|improve this answer


















          • 1




            Saying 'You can't' is directly wrong as shown by my answer ;)
            – Sean Kinsey
            May 21 '10 at 7:03






          • 1




            I stand corrected.
            – Igor Zevaka
            May 21 '10 at 7:43

















          up vote
          0
          down vote













          same as Sean's answer, but instead of creating a script tag, just evaluate it. this ensures that the code is actually ready to use.






          share|improve this answer




















          • Please elaborate. eval() what? The text source of an external script?
            – Steven Vachon
            Dec 29 '13 at 19:18

















          up vote
          0
          down vote













          My strategy, classic example when load jQuery UI, i hope this can help you






          ( function( tools, libs )

          // Iterator
          var require = function( scripts, onEnd );

          // Install all scripts with a copy of scripts
          require( libs.slice(), function()

          alert( "Enjoy :)" );

          );

          // Timeout information
          var ti = setTimeout( function() !window.jQuery.ui )alert( "Timeout !" );

          clearTimeout( ti );

          , 5000 );

          )(

          // Tools

          addEvent : function( evnt, elem, func )

          try

          if( elem.addEventListener )

          elem.addEventListener( evnt, func, false );

          else if( elem.attachEvent )

          var r = elem.attachEvent( "on" + evnt, func );



          return true;

          catch( e )

          return false;





          ,
          [ // Scripts

          "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js",
          "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"

          ]

          );








          share|improve this answer



























            up vote
            0
            down vote













            When using Angular you can take advantage of the fact that every Provider is instantiated before other services are instantiated. You can combine this fact with using xhr and the eval() as mentioned by @Neil. The code would be following:



            app.provider('SomeScriptSyncLoader', function() 

            var resourceUrl = 'http://some/script.js';
            var dummy = ;

            this.$get = function()

            var q = jQuery.ajax(
            type: 'GET', url: resourceUrl, cache: false, async: false
            );

            if (q.status === 200)
            eval(q.responseText); // execute some script synchronously as inline script - eval forces sync processing

            return dummy;
            ;
            );


            To force the Provider to be inialized you need to inject it in at least one other directive/service. Preferably this would be the service which takes advantage of the code loaded by script.



            app.directive('myDirective', ['SomeScriptSyncLoader', function(someScriptSyncLoader) 

            return
            restrict: 'E',
            link: function(scope, element, attrs)
            // some ode
            ,
            template: "this is my template"
            ;
            ]);





            share|improve this answer



























              up vote
              0
              down vote













              I know this is an old question, but maybe someone else read this and find it useful !
              Just created a new components uses ES6 to load scripts dynamically in synchronous way.
              The Project details and source code are on GitHub https://github.com/amgadfahmi/scripty






              share|improve this answer



























                up vote
                0
                down vote













                I may be late to answering this question.



                My current solution is to recursively add <script> tags such that the addition of the subsequent script is in the callback of its predecessor. It assumes that each function contains one function and that function is the same as the file name (minus the extension). This probably isn't the best way to do things, but it works ok.



                Code to consider



                Code directory structure:



                - directory
                ---- index.html
                ---- bundle.js
                ---- test_module/
                -------- a.js
                -------- b.js
                -------- log_num.js
                -------- many_parameters.js


                index.html



                <head>
                <script src="bundle.js"></script>
                </head>


                bundle.js



                // Give JS arrays the .empty() function prototype
                if (!Array.prototype.empty)
                Array.prototype.empty = function()
                return this.length == 0;
                ;
                ;

                function bundle(module_object, list_of_files, directory="")
                if (!list_of_files.empty())
                var current_file = list_of_files.pop()
                var [function_name, extension] = current_file.split(".")
                var new_script = document.createElement("script")
                document.head.appendChild(new_script)

                new_script.src = directory + current_file

                new_script.onload = function()
                module_object[function_name] = eval(function_name)
                bundle(module_object, list_of_files, directory)
                /*
                nullify the function in the global namespace as - assumed - last
                reference to this function garbage collection will remove it. Thus modules
                assembled by this function - bundle(obj, files, dir) - must be called
                FIRST, else one risks overwritting a funciton in the global namespace and
                then deleting it
                */
                eval(function_name + "= undefined")




                var test_module =
                bundle(test_module, ["a.js", "b.js", "log_num.js", "many_parameters.js"], "test_module/")


                a.js



                function a() 
                console.log("a")



                b.js



                function b() 
                console.log("b")



                log_num.js



                // it works with parameters too
                function log_num(num)
                console.log(num)



                many_parameters.js



                function many_parameters(a, b, c) 
                var calc = a - b * c
                console.log(calc)






                share|improve this answer



























                  up vote
                  0
                  down vote













                  There actually is a way to load a list of scripts and execute them synchronously. You need to insert each script tag into the DOM, explicitly setting its async attribute to false:



                  script.async = false;


                  Scripts that have been injected into the DOM are executed asynchronously by default, so you have to set the async attribute to false manually to work around this.



                  Example



                  <script>
                  (function()
                  var scriptNames = [
                  "https://code.jquery.com/jquery.min.js",
                  "example.js"
                  ];
                  for (var i = 0; i < scriptNames.length; i++)
                  var script = document.createElement('script');
                  script.src = scriptNames[i];
                  script.async = false; // This is required for synchronous execution
                  document.head.appendChild(script);

                  // jquery.min.js and example.js will be run in order and synchronously
                  )();
                  </script>

                  <!-- Gotcha: these two script tags may still be run before `jquery.min.js`
                  and `example.js` -->
                  <script src="example2.js"></script>
                  <script>/* ... */<script>


                  References



                  • There is a great article by Jake Archibald of Google about this called Deep dive into the murky waters of script loading.

                  • The WHATWG spec on the tag is a good and thorough description of how tags are loaded.





                  share|improve this answer





























                    up vote
                    0
                    down vote













                    the accepted answer is not correct:



                    the script.async = false; directive only means that html parsing will be paused during script execution. this does not guarantee in which order javascript code will run. see https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/



                    the easiest and most elegant solution which was yet to be mentioned here is using promises, like so:



                     function loadScript(url) 
                    return new Promise((resolve, reject) =>
                    var script = document.createElement('script')
                    script.src = url
                    script.onload = () =>
                    resolve()

                    script.onerror = () =>
                    reject('cannot load script '+ url)

                    document.body.appendChild(script)
                    )



                    and then when you want to execute scripts in order:



                     loadScript('myfirstscript.js').then(() => 
                    console.log('first script ran');
                    loadScript('index.js').then(() =>
                    console.log('second script ran');
                    )
                    )





                    share|improve this answer



























                      up vote
                      -1
                      down vote













                      I use jquery load method applied to div element. something like



                      <div id="js">
                      <!-- script will be inserted here -->
                      </div>

                      ...

                      $("#js").load("path", function() alert("callback!" );


                      You can load scripts several times and each time one script will completely replace the one loaded earlier






                      share|improve this answer




















                        Your Answer






                        StackExchange.ifUsing("editor", function ()
                        StackExchange.using("externalEditor", function ()
                        StackExchange.using("snippets", function ()
                        StackExchange.snippets.init();
                        );
                        );
                        , "code-snippets");

                        StackExchange.ready(function()
                        var channelOptions =
                        tags: "".split(" "),
                        id: "1"
                        ;
                        initTagRenderer("".split(" "), "".split(" "), channelOptions);

                        StackExchange.using("externalEditor", function()
                        // Have to fire editor after snippets, if snippets enabled
                        if (StackExchange.settings.snippets.snippetsEnabled)
                        StackExchange.using("snippets", function()
                        createEditor();
                        );

                        else
                        createEditor();

                        );

                        function createEditor()
                        StackExchange.prepareEditor(
                        heartbeatType: 'answer',
                        convertImagesToLinks: true,
                        noModals: true,
                        showLowRepImageUploadWarning: true,
                        reputationToPostImages: 10,
                        bindNavPrevention: true,
                        postfix: "",
                        imageUploader:
                        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                        allowUrls: true
                        ,
                        onDemand: true,
                        discardSelector: ".discard-answer"
                        ,immediatelyShowMarkdownHelp:true
                        );



                        );













                         

                        draft saved


                        draft discarded


















                        StackExchange.ready(
                        function ()
                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2879509%2fdynamically-loading-javascript-synchronously%23new-answer', 'question_page');

                        );

                        Post as a guest






























                        16 Answers
                        16






                        active

                        oldest

                        votes








                        16 Answers
                        16






                        active

                        oldest

                        votes









                        active

                        oldest

                        votes






                        active

                        oldest

                        votes








                        up vote
                        51
                        down vote



                        accepted










                        There is only one way to synchronously load and execute a script resource, and that is using a synchronous XHR



                        This is an example of how to do this



                        // get some kind of XMLHttpRequest
                        var xhrObj = createXMLHTTPObject();
                        // open and send a synchronous request
                        xhrObj.open('GET', "script.js", false);
                        xhrObj.send('');
                        // add the returned content to a newly created script tag
                        var se = document.createElement('script');
                        se.type = "text/javascript";
                        se.text = xhrObj.responseText;
                        document.getElementsByTagName('head')[0].appendChild(se);


                        But you shouldn't in general use synchronous requests as this will block everything else.
                        But that being said, there are of course scenarios where this is appropriate.



                        I would probably refactor the containing function into an asynchronous pattern though using an onload handler.






                        share|improve this answer


















                        • 1




                          I ended up refactoring so that onload/onreadystate change would work. But this is the correct answer to my original question.
                          – Eric Schoonover
                          May 21 '10 at 7:27






                        • 7




                          Note that this will not work for the (admittedly edge case) of trying to load JS synchronously from file:// on browsers like Chrome where XHR over file:// is prohibited.
                          – Phrogz
                          Jun 20 '12 at 15:54






                        • 2




                          Looks like this fails cross-domain. Is there a way to do dynamic synch injection of 3rd party scripts? Tia.
                          – Steven Francolla
                          Feb 14 '13 at 4:01






                        • 1




                          Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help xhr.spec.whatwg.org
                          – WebolizeR
                          Jan 15 '15 at 11:26






                        • 2




                          This does not wait for the script to be executed synchronously.
                          – Flimm
                          Jul 11 '17 at 10:36














                        up vote
                        51
                        down vote



                        accepted










                        There is only one way to synchronously load and execute a script resource, and that is using a synchronous XHR



                        This is an example of how to do this



                        // get some kind of XMLHttpRequest
                        var xhrObj = createXMLHTTPObject();
                        // open and send a synchronous request
                        xhrObj.open('GET', "script.js", false);
                        xhrObj.send('');
                        // add the returned content to a newly created script tag
                        var se = document.createElement('script');
                        se.type = "text/javascript";
                        se.text = xhrObj.responseText;
                        document.getElementsByTagName('head')[0].appendChild(se);


                        But you shouldn't in general use synchronous requests as this will block everything else.
                        But that being said, there are of course scenarios where this is appropriate.



                        I would probably refactor the containing function into an asynchronous pattern though using an onload handler.






                        share|improve this answer


















                        • 1




                          I ended up refactoring so that onload/onreadystate change would work. But this is the correct answer to my original question.
                          – Eric Schoonover
                          May 21 '10 at 7:27






                        • 7




                          Note that this will not work for the (admittedly edge case) of trying to load JS synchronously from file:// on browsers like Chrome where XHR over file:// is prohibited.
                          – Phrogz
                          Jun 20 '12 at 15:54






                        • 2




                          Looks like this fails cross-domain. Is there a way to do dynamic synch injection of 3rd party scripts? Tia.
                          – Steven Francolla
                          Feb 14 '13 at 4:01






                        • 1




                          Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help xhr.spec.whatwg.org
                          – WebolizeR
                          Jan 15 '15 at 11:26






                        • 2




                          This does not wait for the script to be executed synchronously.
                          – Flimm
                          Jul 11 '17 at 10:36












                        up vote
                        51
                        down vote



                        accepted







                        up vote
                        51
                        down vote



                        accepted






                        There is only one way to synchronously load and execute a script resource, and that is using a synchronous XHR



                        This is an example of how to do this



                        // get some kind of XMLHttpRequest
                        var xhrObj = createXMLHTTPObject();
                        // open and send a synchronous request
                        xhrObj.open('GET', "script.js", false);
                        xhrObj.send('');
                        // add the returned content to a newly created script tag
                        var se = document.createElement('script');
                        se.type = "text/javascript";
                        se.text = xhrObj.responseText;
                        document.getElementsByTagName('head')[0].appendChild(se);


                        But you shouldn't in general use synchronous requests as this will block everything else.
                        But that being said, there are of course scenarios where this is appropriate.



                        I would probably refactor the containing function into an asynchronous pattern though using an onload handler.






                        share|improve this answer














                        There is only one way to synchronously load and execute a script resource, and that is using a synchronous XHR



                        This is an example of how to do this



                        // get some kind of XMLHttpRequest
                        var xhrObj = createXMLHTTPObject();
                        // open and send a synchronous request
                        xhrObj.open('GET', "script.js", false);
                        xhrObj.send('');
                        // add the returned content to a newly created script tag
                        var se = document.createElement('script');
                        se.type = "text/javascript";
                        se.text = xhrObj.responseText;
                        document.getElementsByTagName('head')[0].appendChild(se);


                        But you shouldn't in general use synchronous requests as this will block everything else.
                        But that being said, there are of course scenarios where this is appropriate.



                        I would probably refactor the containing function into an asynchronous pattern though using an onload handler.







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Jun 19 '14 at 9:30









                        Fabio Milheiro

                        4,107124183




                        4,107124183










                        answered May 21 '10 at 7:02









                        Sean Kinsey

                        30.6k74566




                        30.6k74566







                        • 1




                          I ended up refactoring so that onload/onreadystate change would work. But this is the correct answer to my original question.
                          – Eric Schoonover
                          May 21 '10 at 7:27






                        • 7




                          Note that this will not work for the (admittedly edge case) of trying to load JS synchronously from file:// on browsers like Chrome where XHR over file:// is prohibited.
                          – Phrogz
                          Jun 20 '12 at 15:54






                        • 2




                          Looks like this fails cross-domain. Is there a way to do dynamic synch injection of 3rd party scripts? Tia.
                          – Steven Francolla
                          Feb 14 '13 at 4:01






                        • 1




                          Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help xhr.spec.whatwg.org
                          – WebolizeR
                          Jan 15 '15 at 11:26






                        • 2




                          This does not wait for the script to be executed synchronously.
                          – Flimm
                          Jul 11 '17 at 10:36












                        • 1




                          I ended up refactoring so that onload/onreadystate change would work. But this is the correct answer to my original question.
                          – Eric Schoonover
                          May 21 '10 at 7:27






                        • 7




                          Note that this will not work for the (admittedly edge case) of trying to load JS synchronously from file:// on browsers like Chrome where XHR over file:// is prohibited.
                          – Phrogz
                          Jun 20 '12 at 15:54






                        • 2




                          Looks like this fails cross-domain. Is there a way to do dynamic synch injection of 3rd party scripts? Tia.
                          – Steven Francolla
                          Feb 14 '13 at 4:01






                        • 1




                          Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help xhr.spec.whatwg.org
                          – WebolizeR
                          Jan 15 '15 at 11:26






                        • 2




                          This does not wait for the script to be executed synchronously.
                          – Flimm
                          Jul 11 '17 at 10:36







                        1




                        1




                        I ended up refactoring so that onload/onreadystate change would work. But this is the correct answer to my original question.
                        – Eric Schoonover
                        May 21 '10 at 7:27




                        I ended up refactoring so that onload/onreadystate change would work. But this is the correct answer to my original question.
                        – Eric Schoonover
                        May 21 '10 at 7:27




                        7




                        7




                        Note that this will not work for the (admittedly edge case) of trying to load JS synchronously from file:// on browsers like Chrome where XHR over file:// is prohibited.
                        – Phrogz
                        Jun 20 '12 at 15:54




                        Note that this will not work for the (admittedly edge case) of trying to load JS synchronously from file:// on browsers like Chrome where XHR over file:// is prohibited.
                        – Phrogz
                        Jun 20 '12 at 15:54




                        2




                        2




                        Looks like this fails cross-domain. Is there a way to do dynamic synch injection of 3rd party scripts? Tia.
                        – Steven Francolla
                        Feb 14 '13 at 4:01




                        Looks like this fails cross-domain. Is there a way to do dynamic synch injection of 3rd party scripts? Tia.
                        – Steven Francolla
                        Feb 14 '13 at 4:01




                        1




                        1




                        Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help xhr.spec.whatwg.org
                        – WebolizeR
                        Jan 15 '15 at 11:26




                        Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help xhr.spec.whatwg.org
                        – WebolizeR
                        Jan 15 '15 at 11:26




                        2




                        2




                        This does not wait for the script to be executed synchronously.
                        – Flimm
                        Jul 11 '17 at 10:36




                        This does not wait for the script to be executed synchronously.
                        – Flimm
                        Jul 11 '17 at 10:36












                        up vote
                        34
                        down vote













                        The accepted answer is NOT correct.



                        Loading a file synchronously is not the same as executing the file synchronously - which is what the OP requested.



                        The accepted answer loads the file sync, but does nothing more than append a script tag to the DOM. Just because appendChild() has returned does not in anyway guarantee that the script has finished executing and it's members are initialised for use.



                        The only (see caveat) way to achieve the OPs question is to sync load the script over XHR as stated, then read as text and pass into either eval() or a new Function() call and wait for that function to return. This is the only way to guarantee the script is loaded AND executed synchronously.



                        I make no comment as to whether this is a wise thing to do either from a UI or security perspective, but there are certainly use cases that justify a sync load & execute.



                        Caveat:
                        Unless you're using web workers in which case just call loadScripts();






                        share|improve this answer


























                          up vote
                          34
                          down vote













                          The accepted answer is NOT correct.



                          Loading a file synchronously is not the same as executing the file synchronously - which is what the OP requested.



                          The accepted answer loads the file sync, but does nothing more than append a script tag to the DOM. Just because appendChild() has returned does not in anyway guarantee that the script has finished executing and it's members are initialised for use.



                          The only (see caveat) way to achieve the OPs question is to sync load the script over XHR as stated, then read as text and pass into either eval() or a new Function() call and wait for that function to return. This is the only way to guarantee the script is loaded AND executed synchronously.



                          I make no comment as to whether this is a wise thing to do either from a UI or security perspective, but there are certainly use cases that justify a sync load & execute.



                          Caveat:
                          Unless you're using web workers in which case just call loadScripts();






                          share|improve this answer
























                            up vote
                            34
                            down vote










                            up vote
                            34
                            down vote









                            The accepted answer is NOT correct.



                            Loading a file synchronously is not the same as executing the file synchronously - which is what the OP requested.



                            The accepted answer loads the file sync, but does nothing more than append a script tag to the DOM. Just because appendChild() has returned does not in anyway guarantee that the script has finished executing and it's members are initialised for use.



                            The only (see caveat) way to achieve the OPs question is to sync load the script over XHR as stated, then read as text and pass into either eval() or a new Function() call and wait for that function to return. This is the only way to guarantee the script is loaded AND executed synchronously.



                            I make no comment as to whether this is a wise thing to do either from a UI or security perspective, but there are certainly use cases that justify a sync load & execute.



                            Caveat:
                            Unless you're using web workers in which case just call loadScripts();






                            share|improve this answer














                            The accepted answer is NOT correct.



                            Loading a file synchronously is not the same as executing the file synchronously - which is what the OP requested.



                            The accepted answer loads the file sync, but does nothing more than append a script tag to the DOM. Just because appendChild() has returned does not in anyway guarantee that the script has finished executing and it's members are initialised for use.



                            The only (see caveat) way to achieve the OPs question is to sync load the script over XHR as stated, then read as text and pass into either eval() or a new Function() call and wait for that function to return. This is the only way to guarantee the script is loaded AND executed synchronously.



                            I make no comment as to whether this is a wise thing to do either from a UI or security perspective, but there are certainly use cases that justify a sync load & execute.



                            Caveat:
                            Unless you're using web workers in which case just call loadScripts();







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Jul 11 '17 at 10:35









                            Flimm

                            48.8k23130152




                            48.8k23130152










                            answered Feb 12 '14 at 14:36









                            Neil

                            880810




                            880810




















                                up vote
                                9
                                down vote













                                This is the code that I'm using for multiple file load in my app.



                                Utilities.require = function (file, callback) 
                                callback = callback ;

                                Utilities.requireFiles = function ()
                                var index = 0;
                                return function (files, callback)
                                index += 1;
                                Utilities.require(files[index - 1], callBackCounter);

                                function callBackCounter()
                                if (index === files.length)
                                index = 0;
                                callback();
                                else
                                Utilities.requireFiles(files, callback);

                                ;
                                ;
                                ();


                                And this utilities can be used by



                                Utilities.requireFiles(["url1", "url2",....], function()
                                //Call the init function in the loaded file.
                                )





                                share|improve this answer
















                                • 1




                                  Does that work for nested items aswell? Say if you require more files inside the files you require?
                                  – Johan
                                  Nov 16 '12 at 12:18






                                • 4




                                  This is async, not syncronues!
                                  – momo
                                  Jul 13 '13 at 10:18






                                • 2




                                  the callback function is called upon the specified scripts are loaded. Isn't it good enough?
                                  – Kenji Noguchi
                                  Jan 27 '14 at 0:45










                                • async is not sync. does not answer OP.
                                  – catbadger
                                  Jun 23 '17 at 14:37














                                up vote
                                9
                                down vote













                                This is the code that I'm using for multiple file load in my app.



                                Utilities.require = function (file, callback) 
                                callback = callback ;

                                Utilities.requireFiles = function ()
                                var index = 0;
                                return function (files, callback)
                                index += 1;
                                Utilities.require(files[index - 1], callBackCounter);

                                function callBackCounter()
                                if (index === files.length)
                                index = 0;
                                callback();
                                else
                                Utilities.requireFiles(files, callback);

                                ;
                                ;
                                ();


                                And this utilities can be used by



                                Utilities.requireFiles(["url1", "url2",....], function()
                                //Call the init function in the loaded file.
                                )





                                share|improve this answer
















                                • 1




                                  Does that work for nested items aswell? Say if you require more files inside the files you require?
                                  – Johan
                                  Nov 16 '12 at 12:18






                                • 4




                                  This is async, not syncronues!
                                  – momo
                                  Jul 13 '13 at 10:18






                                • 2




                                  the callback function is called upon the specified scripts are loaded. Isn't it good enough?
                                  – Kenji Noguchi
                                  Jan 27 '14 at 0:45










                                • async is not sync. does not answer OP.
                                  – catbadger
                                  Jun 23 '17 at 14:37












                                up vote
                                9
                                down vote










                                up vote
                                9
                                down vote









                                This is the code that I'm using for multiple file load in my app.



                                Utilities.require = function (file, callback) 
                                callback = callback ;

                                Utilities.requireFiles = function ()
                                var index = 0;
                                return function (files, callback)
                                index += 1;
                                Utilities.require(files[index - 1], callBackCounter);

                                function callBackCounter()
                                if (index === files.length)
                                index = 0;
                                callback();
                                else
                                Utilities.requireFiles(files, callback);

                                ;
                                ;
                                ();


                                And this utilities can be used by



                                Utilities.requireFiles(["url1", "url2",....], function()
                                //Call the init function in the loaded file.
                                )





                                share|improve this answer












                                This is the code that I'm using for multiple file load in my app.



                                Utilities.require = function (file, callback) 
                                callback = callback ;

                                Utilities.requireFiles = function ()
                                var index = 0;
                                return function (files, callback)
                                index += 1;
                                Utilities.require(files[index - 1], callBackCounter);

                                function callBackCounter()
                                if (index === files.length)
                                index = 0;
                                callback();
                                else
                                Utilities.requireFiles(files, callback);

                                ;
                                ;
                                ();


                                And this utilities can be used by



                                Utilities.requireFiles(["url1", "url2",....], function()
                                //Call the init function in the loaded file.
                                )






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Jun 19 '12 at 10:42









                                Alan Joseph

                                10711




                                10711







                                • 1




                                  Does that work for nested items aswell? Say if you require more files inside the files you require?
                                  – Johan
                                  Nov 16 '12 at 12:18






                                • 4




                                  This is async, not syncronues!
                                  – momo
                                  Jul 13 '13 at 10:18






                                • 2




                                  the callback function is called upon the specified scripts are loaded. Isn't it good enough?
                                  – Kenji Noguchi
                                  Jan 27 '14 at 0:45










                                • async is not sync. does not answer OP.
                                  – catbadger
                                  Jun 23 '17 at 14:37












                                • 1




                                  Does that work for nested items aswell? Say if you require more files inside the files you require?
                                  – Johan
                                  Nov 16 '12 at 12:18






                                • 4




                                  This is async, not syncronues!
                                  – momo
                                  Jul 13 '13 at 10:18






                                • 2




                                  the callback function is called upon the specified scripts are loaded. Isn't it good enough?
                                  – Kenji Noguchi
                                  Jan 27 '14 at 0:45










                                • async is not sync. does not answer OP.
                                  – catbadger
                                  Jun 23 '17 at 14:37







                                1




                                1




                                Does that work for nested items aswell? Say if you require more files inside the files you require?
                                – Johan
                                Nov 16 '12 at 12:18




                                Does that work for nested items aswell? Say if you require more files inside the files you require?
                                – Johan
                                Nov 16 '12 at 12:18




                                4




                                4




                                This is async, not syncronues!
                                – momo
                                Jul 13 '13 at 10:18




                                This is async, not syncronues!
                                – momo
                                Jul 13 '13 at 10:18




                                2




                                2




                                the callback function is called upon the specified scripts are loaded. Isn't it good enough?
                                – Kenji Noguchi
                                Jan 27 '14 at 0:45




                                the callback function is called upon the specified scripts are loaded. Isn't it good enough?
                                – Kenji Noguchi
                                Jan 27 '14 at 0:45












                                async is not sync. does not answer OP.
                                – catbadger
                                Jun 23 '17 at 14:37




                                async is not sync. does not answer OP.
                                – catbadger
                                Jun 23 '17 at 14:37










                                up vote
                                5
                                down vote













                                The most Node.js-like implementation I could come up with was able to load JS files synchonously, and use them as objects/modules



                                var scriptCache = ;
                                var paths = ;
                                function Import(path)

                                var index = 0;
                                if((index = paths.indexOf(path)) != -1) //If we already imported this module

                                return scriptCache [index];


                                var request, script, source;
                                var fullPath = window.location.protocol + '//' + window.location.host + '/' + path;

                                request = new XMLHttpRequest();
                                request.open('GET', fullPath, false);
                                request.send();

                                source = request.responseText;

                                var module = (function concealedEval()
                                eval(source);
                                return exports;
                                )();

                                scriptCache.push(module);
                                paths.push(path);

                                return module;



                                An example source (addobjects.js):



                                function AddTwoObjects(a, b)

                                return a + b;


                                this.exports = AddTwoObjects;


                                And use it like this:



                                var AddTwoObjects = Import('addobjects.js');
                                alert(AddTwoObjects(3, 4)); //7
                                //or even like this:
                                alert(Import('addobjects.js')(3, 4)); //7





                                share|improve this answer


























                                  up vote
                                  5
                                  down vote













                                  The most Node.js-like implementation I could come up with was able to load JS files synchonously, and use them as objects/modules



                                  var scriptCache = ;
                                  var paths = ;
                                  function Import(path)

                                  var index = 0;
                                  if((index = paths.indexOf(path)) != -1) //If we already imported this module

                                  return scriptCache [index];


                                  var request, script, source;
                                  var fullPath = window.location.protocol + '//' + window.location.host + '/' + path;

                                  request = new XMLHttpRequest();
                                  request.open('GET', fullPath, false);
                                  request.send();

                                  source = request.responseText;

                                  var module = (function concealedEval()
                                  eval(source);
                                  return exports;
                                  )();

                                  scriptCache.push(module);
                                  paths.push(path);

                                  return module;



                                  An example source (addobjects.js):



                                  function AddTwoObjects(a, b)

                                  return a + b;


                                  this.exports = AddTwoObjects;


                                  And use it like this:



                                  var AddTwoObjects = Import('addobjects.js');
                                  alert(AddTwoObjects(3, 4)); //7
                                  //or even like this:
                                  alert(Import('addobjects.js')(3, 4)); //7





                                  share|improve this answer
























                                    up vote
                                    5
                                    down vote










                                    up vote
                                    5
                                    down vote









                                    The most Node.js-like implementation I could come up with was able to load JS files synchonously, and use them as objects/modules



                                    var scriptCache = ;
                                    var paths = ;
                                    function Import(path)

                                    var index = 0;
                                    if((index = paths.indexOf(path)) != -1) //If we already imported this module

                                    return scriptCache [index];


                                    var request, script, source;
                                    var fullPath = window.location.protocol + '//' + window.location.host + '/' + path;

                                    request = new XMLHttpRequest();
                                    request.open('GET', fullPath, false);
                                    request.send();

                                    source = request.responseText;

                                    var module = (function concealedEval()
                                    eval(source);
                                    return exports;
                                    )();

                                    scriptCache.push(module);
                                    paths.push(path);

                                    return module;



                                    An example source (addobjects.js):



                                    function AddTwoObjects(a, b)

                                    return a + b;


                                    this.exports = AddTwoObjects;


                                    And use it like this:



                                    var AddTwoObjects = Import('addobjects.js');
                                    alert(AddTwoObjects(3, 4)); //7
                                    //or even like this:
                                    alert(Import('addobjects.js')(3, 4)); //7





                                    share|improve this answer














                                    The most Node.js-like implementation I could come up with was able to load JS files synchonously, and use them as objects/modules



                                    var scriptCache = ;
                                    var paths = ;
                                    function Import(path)

                                    var index = 0;
                                    if((index = paths.indexOf(path)) != -1) //If we already imported this module

                                    return scriptCache [index];


                                    var request, script, source;
                                    var fullPath = window.location.protocol + '//' + window.location.host + '/' + path;

                                    request = new XMLHttpRequest();
                                    request.open('GET', fullPath, false);
                                    request.send();

                                    source = request.responseText;

                                    var module = (function concealedEval()
                                    eval(source);
                                    return exports;
                                    )();

                                    scriptCache.push(module);
                                    paths.push(path);

                                    return module;



                                    An example source (addobjects.js):



                                    function AddTwoObjects(a, b)

                                    return a + b;


                                    this.exports = AddTwoObjects;


                                    And use it like this:



                                    var AddTwoObjects = Import('addobjects.js');
                                    alert(AddTwoObjects(3, 4)); //7
                                    //or even like this:
                                    alert(Import('addobjects.js')(3, 4)); //7






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Aug 8 '16 at 15:53

























                                    answered Aug 8 '16 at 14:36









                                    Jaggler3

                                    12528




                                    12528




















                                        up vote
                                        3
                                        down vote













                                        I had the following problem(s) with the existing answers to this question (and variations of this question on other stackoverflow threads):



                                        • None of the loaded code was debuggable

                                        • Many of the solutions required callbacks to know when loading was finished instead of truly blocking, meaning I would get execution errors from immediately calling loaded (ie loading) code.

                                        Or, slightly more accurately:



                                        • None of the loaded code was debuggable (except from the HTML script tag block, if and only if the solution added a script elements to the dom, and never ever as individual viewable scripts.) => Given how many scripts I have to load (and debug), this was unacceptable.

                                        • Solutions using 'onreadystatechange' or 'onload' events failed to block, which was a big problem since the code originally loaded dynamic scripts synchronously using 'require([filename, 'dojo/domReady']);' and I was stripping out dojo.

                                        My final solution, which loads the script before returning, AND has all scripts properly accessible in the debugger (for Chrome at least) is as follows:



                                        WARNING: The following code should PROBABLY be used only in 'development' mode. (For 'release' mode I recommend prepackaging and minification WITHOUT dynamic script loading, or at least without eval).



                                        //Code User TODO: you must create and set your own 'noEval' variable

                                        require = function require(inFileName)

                                        var aRequest
                                        ,aScript
                                        ,aScriptSource
                                        ;

                                        //setup the full relative filename
                                        inFileName =
                                        window.location.protocol + '//'
                                        + window.location.host + '/'
                                        + inFileName;

                                        //synchronously get the code
                                        aRequest = new XMLHttpRequest();
                                        aRequest.open('GET', inFileName, false);
                                        aRequest.send();

                                        //set the returned script text while adding special comment to auto include in debugger source listing:
                                        aScriptSource = aRequest.responseText + 'n////# sourceURL=' + inFileName + 'n';

                                        if(noEval)//<== **TODO: Provide + set condition variable yourself!!!!**

                                        //create a dom element to hold the code
                                        aScript = document.createElement('script');
                                        aScript.type = 'text/javascript';

                                        //set the script tag text, including the debugger id at the end!!
                                        aScript.text = aScriptSource;

                                        //append the code to the dom
                                        document.getElementsByTagName('body')[0].appendChild(aScript);

                                        else

                                        eval(aScriptSource);

                                        ;





                                        share|improve this answer
























                                          up vote
                                          3
                                          down vote













                                          I had the following problem(s) with the existing answers to this question (and variations of this question on other stackoverflow threads):



                                          • None of the loaded code was debuggable

                                          • Many of the solutions required callbacks to know when loading was finished instead of truly blocking, meaning I would get execution errors from immediately calling loaded (ie loading) code.

                                          Or, slightly more accurately:



                                          • None of the loaded code was debuggable (except from the HTML script tag block, if and only if the solution added a script elements to the dom, and never ever as individual viewable scripts.) => Given how many scripts I have to load (and debug), this was unacceptable.

                                          • Solutions using 'onreadystatechange' or 'onload' events failed to block, which was a big problem since the code originally loaded dynamic scripts synchronously using 'require([filename, 'dojo/domReady']);' and I was stripping out dojo.

                                          My final solution, which loads the script before returning, AND has all scripts properly accessible in the debugger (for Chrome at least) is as follows:



                                          WARNING: The following code should PROBABLY be used only in 'development' mode. (For 'release' mode I recommend prepackaging and minification WITHOUT dynamic script loading, or at least without eval).



                                          //Code User TODO: you must create and set your own 'noEval' variable

                                          require = function require(inFileName)

                                          var aRequest
                                          ,aScript
                                          ,aScriptSource
                                          ;

                                          //setup the full relative filename
                                          inFileName =
                                          window.location.protocol + '//'
                                          + window.location.host + '/'
                                          + inFileName;

                                          //synchronously get the code
                                          aRequest = new XMLHttpRequest();
                                          aRequest.open('GET', inFileName, false);
                                          aRequest.send();

                                          //set the returned script text while adding special comment to auto include in debugger source listing:
                                          aScriptSource = aRequest.responseText + 'n////# sourceURL=' + inFileName + 'n';

                                          if(noEval)//<== **TODO: Provide + set condition variable yourself!!!!**

                                          //create a dom element to hold the code
                                          aScript = document.createElement('script');
                                          aScript.type = 'text/javascript';

                                          //set the script tag text, including the debugger id at the end!!
                                          aScript.text = aScriptSource;

                                          //append the code to the dom
                                          document.getElementsByTagName('body')[0].appendChild(aScript);

                                          else

                                          eval(aScriptSource);

                                          ;





                                          share|improve this answer






















                                            up vote
                                            3
                                            down vote










                                            up vote
                                            3
                                            down vote









                                            I had the following problem(s) with the existing answers to this question (and variations of this question on other stackoverflow threads):



                                            • None of the loaded code was debuggable

                                            • Many of the solutions required callbacks to know when loading was finished instead of truly blocking, meaning I would get execution errors from immediately calling loaded (ie loading) code.

                                            Or, slightly more accurately:



                                            • None of the loaded code was debuggable (except from the HTML script tag block, if and only if the solution added a script elements to the dom, and never ever as individual viewable scripts.) => Given how many scripts I have to load (and debug), this was unacceptable.

                                            • Solutions using 'onreadystatechange' or 'onload' events failed to block, which was a big problem since the code originally loaded dynamic scripts synchronously using 'require([filename, 'dojo/domReady']);' and I was stripping out dojo.

                                            My final solution, which loads the script before returning, AND has all scripts properly accessible in the debugger (for Chrome at least) is as follows:



                                            WARNING: The following code should PROBABLY be used only in 'development' mode. (For 'release' mode I recommend prepackaging and minification WITHOUT dynamic script loading, or at least without eval).



                                            //Code User TODO: you must create and set your own 'noEval' variable

                                            require = function require(inFileName)

                                            var aRequest
                                            ,aScript
                                            ,aScriptSource
                                            ;

                                            //setup the full relative filename
                                            inFileName =
                                            window.location.protocol + '//'
                                            + window.location.host + '/'
                                            + inFileName;

                                            //synchronously get the code
                                            aRequest = new XMLHttpRequest();
                                            aRequest.open('GET', inFileName, false);
                                            aRequest.send();

                                            //set the returned script text while adding special comment to auto include in debugger source listing:
                                            aScriptSource = aRequest.responseText + 'n////# sourceURL=' + inFileName + 'n';

                                            if(noEval)//<== **TODO: Provide + set condition variable yourself!!!!**

                                            //create a dom element to hold the code
                                            aScript = document.createElement('script');
                                            aScript.type = 'text/javascript';

                                            //set the script tag text, including the debugger id at the end!!
                                            aScript.text = aScriptSource;

                                            //append the code to the dom
                                            document.getElementsByTagName('body')[0].appendChild(aScript);

                                            else

                                            eval(aScriptSource);

                                            ;





                                            share|improve this answer












                                            I had the following problem(s) with the existing answers to this question (and variations of this question on other stackoverflow threads):



                                            • None of the loaded code was debuggable

                                            • Many of the solutions required callbacks to know when loading was finished instead of truly blocking, meaning I would get execution errors from immediately calling loaded (ie loading) code.

                                            Or, slightly more accurately:



                                            • None of the loaded code was debuggable (except from the HTML script tag block, if and only if the solution added a script elements to the dom, and never ever as individual viewable scripts.) => Given how many scripts I have to load (and debug), this was unacceptable.

                                            • Solutions using 'onreadystatechange' or 'onload' events failed to block, which was a big problem since the code originally loaded dynamic scripts synchronously using 'require([filename, 'dojo/domReady']);' and I was stripping out dojo.

                                            My final solution, which loads the script before returning, AND has all scripts properly accessible in the debugger (for Chrome at least) is as follows:



                                            WARNING: The following code should PROBABLY be used only in 'development' mode. (For 'release' mode I recommend prepackaging and minification WITHOUT dynamic script loading, or at least without eval).



                                            //Code User TODO: you must create and set your own 'noEval' variable

                                            require = function require(inFileName)

                                            var aRequest
                                            ,aScript
                                            ,aScriptSource
                                            ;

                                            //setup the full relative filename
                                            inFileName =
                                            window.location.protocol + '//'
                                            + window.location.host + '/'
                                            + inFileName;

                                            //synchronously get the code
                                            aRequest = new XMLHttpRequest();
                                            aRequest.open('GET', inFileName, false);
                                            aRequest.send();

                                            //set the returned script text while adding special comment to auto include in debugger source listing:
                                            aScriptSource = aRequest.responseText + 'n////# sourceURL=' + inFileName + 'n';

                                            if(noEval)//<== **TODO: Provide + set condition variable yourself!!!!**

                                            //create a dom element to hold the code
                                            aScript = document.createElement('script');
                                            aScript.type = 'text/javascript';

                                            //set the script tag text, including the debugger id at the end!!
                                            aScript.text = aScriptSource;

                                            //append the code to the dom
                                            document.getElementsByTagName('body')[0].appendChild(aScript);

                                            else

                                            eval(aScriptSource);

                                            ;






                                            share|improve this answer












                                            share|improve this answer



                                            share|improve this answer










                                            answered Feb 15 '14 at 8:34









                                            jeremykentbgross

                                            1546




                                            1546




















                                                up vote
                                                2
                                                down vote













                                                var xhrObj = new XMLHttpRequest();
                                                xhrObj.open('GET', '/filename.js', false);
                                                xhrObj.send(null);
                                                eval(xhrObj.responseText);


                                                If this is a cross-domain request, it will not work. In that case you have to upload the requested file to your server, or make a mirror php that outputs it, and require that php.



                                                With jquery (works with cross-domain request too):



                                                $.getScript('/filename.js',callbackFunction);


                                                callbackFunction will be called synchronously.



                                                For loading more scripts see this thread.






                                                share|improve this answer


























                                                  up vote
                                                  2
                                                  down vote













                                                  var xhrObj = new XMLHttpRequest();
                                                  xhrObj.open('GET', '/filename.js', false);
                                                  xhrObj.send(null);
                                                  eval(xhrObj.responseText);


                                                  If this is a cross-domain request, it will not work. In that case you have to upload the requested file to your server, or make a mirror php that outputs it, and require that php.



                                                  With jquery (works with cross-domain request too):



                                                  $.getScript('/filename.js',callbackFunction);


                                                  callbackFunction will be called synchronously.



                                                  For loading more scripts see this thread.






                                                  share|improve this answer
























                                                    up vote
                                                    2
                                                    down vote










                                                    up vote
                                                    2
                                                    down vote









                                                    var xhrObj = new XMLHttpRequest();
                                                    xhrObj.open('GET', '/filename.js', false);
                                                    xhrObj.send(null);
                                                    eval(xhrObj.responseText);


                                                    If this is a cross-domain request, it will not work. In that case you have to upload the requested file to your server, or make a mirror php that outputs it, and require that php.



                                                    With jquery (works with cross-domain request too):



                                                    $.getScript('/filename.js',callbackFunction);


                                                    callbackFunction will be called synchronously.



                                                    For loading more scripts see this thread.






                                                    share|improve this answer














                                                    var xhrObj = new XMLHttpRequest();
                                                    xhrObj.open('GET', '/filename.js', false);
                                                    xhrObj.send(null);
                                                    eval(xhrObj.responseText);


                                                    If this is a cross-domain request, it will not work. In that case you have to upload the requested file to your server, or make a mirror php that outputs it, and require that php.



                                                    With jquery (works with cross-domain request too):



                                                    $.getScript('/filename.js',callbackFunction);


                                                    callbackFunction will be called synchronously.



                                                    For loading more scripts see this thread.







                                                    share|improve this answer














                                                    share|improve this answer



                                                    share|improve this answer








                                                    edited May 23 '17 at 12:18









                                                    Community

                                                    11




                                                    11










                                                    answered Jul 16 '14 at 10:07







                                                    user669677



























                                                        up vote
                                                        1
                                                        down vote













                                                        If you need to load an arbitrary number of scripts and only proceed when the last one is done, and you cannot use XHR (e.g. due to CORS limitations) you can do the following. It is not synchronous, but does allow a callback to occur exactly when the last file is done loading:



                                                        // Load <script> elements for all uris
                                                        // Invoke the whenDone callback function after the last URI has loaded
                                                        function loadScripts(uris,whenDone)
                                                        if (!uris.length) whenDone && whenDone();
                                                        else
                                                        for (var wait=,i=uris.length;i--;)
                                                        var tag = document.createElement('script');
                                                        tag.type = 'text/javascript';
                                                        tag.src = uris[i];
                                                        if (whenDone)
                                                        wait.push(tag)
                                                        tag.onload = maybeDone;
                                                        tag.onreadystatechange = maybeDone; // For IE8-

                                                        document.body.appendChild(tag);


                                                        function maybeDone() this.readyState==='complete')
                                                        // Pull the tags out based on the actual element in case IE ever
                                                        // intermingles the onload and onreadystatechange handlers for the same
                                                        // script block before notifying for another one.
                                                        for (var i=wait.length;i--;) if (wait[i]==this) wait.splice(i,1);
                                                        if (!wait.length) whenDone();





                                                        Edit: Updated to work with IE7, IE8, and IE9 (in quirks mode). These IE versions do not fire an onload event, but do for onreadystatechange. IE9 in standards mode fires both (with onreadystatechange for all scripts firing before onload for any).



                                                        Based on this page there may be a small chance that old versions of IE will never send an onreadystatechange event with readyState=='complete'; if this is the case (I could not reproduce this problem) then the above script will fail and your callback will never be invoked.






                                                        share|improve this answer






















                                                        • I think there may be some per-browser issues with getting the "load" event reliably (or at all), based on various grumblings I've seen from script loader authors.
                                                          – Pointy
                                                          Jun 20 '12 at 16:14










                                                        • @Pointy Ooh, that's good to know; thanks. I'll have to look into that more.
                                                          – Phrogz
                                                          Jun 20 '12 at 16:16






                                                        • 1




                                                          I'm not very familiar with the issues; I've been looking through the source of LABjs and mostly it's just making me confused. (I picked that one because the author is an acquaintance.)
                                                          – Pointy
                                                          Jun 20 '12 at 16:26










                                                        • @Pointy Thanks to your note I found this page which describes the need to use onreadystatechange for IE. In testing, IE9 in standards mode does not require this, but older versions do. I've updated my answer with code that works in the current versions of all major browsers, and also IE7 and IE8.
                                                          – Phrogz
                                                          Jun 20 '12 at 19:42















                                                        up vote
                                                        1
                                                        down vote













                                                        If you need to load an arbitrary number of scripts and only proceed when the last one is done, and you cannot use XHR (e.g. due to CORS limitations) you can do the following. It is not synchronous, but does allow a callback to occur exactly when the last file is done loading:



                                                        // Load <script> elements for all uris
                                                        // Invoke the whenDone callback function after the last URI has loaded
                                                        function loadScripts(uris,whenDone)
                                                        if (!uris.length) whenDone && whenDone();
                                                        else
                                                        for (var wait=,i=uris.length;i--;)
                                                        var tag = document.createElement('script');
                                                        tag.type = 'text/javascript';
                                                        tag.src = uris[i];
                                                        if (whenDone)
                                                        wait.push(tag)
                                                        tag.onload = maybeDone;
                                                        tag.onreadystatechange = maybeDone; // For IE8-

                                                        document.body.appendChild(tag);


                                                        function maybeDone() this.readyState==='complete')
                                                        // Pull the tags out based on the actual element in case IE ever
                                                        // intermingles the onload and onreadystatechange handlers for the same
                                                        // script block before notifying for another one.
                                                        for (var i=wait.length;i--;) if (wait[i]==this) wait.splice(i,1);
                                                        if (!wait.length) whenDone();





                                                        Edit: Updated to work with IE7, IE8, and IE9 (in quirks mode). These IE versions do not fire an onload event, but do for onreadystatechange. IE9 in standards mode fires both (with onreadystatechange for all scripts firing before onload for any).



                                                        Based on this page there may be a small chance that old versions of IE will never send an onreadystatechange event with readyState=='complete'; if this is the case (I could not reproduce this problem) then the above script will fail and your callback will never be invoked.






                                                        share|improve this answer






















                                                        • I think there may be some per-browser issues with getting the "load" event reliably (or at all), based on various grumblings I've seen from script loader authors.
                                                          – Pointy
                                                          Jun 20 '12 at 16:14










                                                        • @Pointy Ooh, that's good to know; thanks. I'll have to look into that more.
                                                          – Phrogz
                                                          Jun 20 '12 at 16:16






                                                        • 1




                                                          I'm not very familiar with the issues; I've been looking through the source of LABjs and mostly it's just making me confused. (I picked that one because the author is an acquaintance.)
                                                          – Pointy
                                                          Jun 20 '12 at 16:26










                                                        • @Pointy Thanks to your note I found this page which describes the need to use onreadystatechange for IE. In testing, IE9 in standards mode does not require this, but older versions do. I've updated my answer with code that works in the current versions of all major browsers, and also IE7 and IE8.
                                                          – Phrogz
                                                          Jun 20 '12 at 19:42













                                                        up vote
                                                        1
                                                        down vote










                                                        up vote
                                                        1
                                                        down vote









                                                        If you need to load an arbitrary number of scripts and only proceed when the last one is done, and you cannot use XHR (e.g. due to CORS limitations) you can do the following. It is not synchronous, but does allow a callback to occur exactly when the last file is done loading:



                                                        // Load <script> elements for all uris
                                                        // Invoke the whenDone callback function after the last URI has loaded
                                                        function loadScripts(uris,whenDone)
                                                        if (!uris.length) whenDone && whenDone();
                                                        else
                                                        for (var wait=,i=uris.length;i--;)
                                                        var tag = document.createElement('script');
                                                        tag.type = 'text/javascript';
                                                        tag.src = uris[i];
                                                        if (whenDone)
                                                        wait.push(tag)
                                                        tag.onload = maybeDone;
                                                        tag.onreadystatechange = maybeDone; // For IE8-

                                                        document.body.appendChild(tag);


                                                        function maybeDone() this.readyState==='complete')
                                                        // Pull the tags out based on the actual element in case IE ever
                                                        // intermingles the onload and onreadystatechange handlers for the same
                                                        // script block before notifying for another one.
                                                        for (var i=wait.length;i--;) if (wait[i]==this) wait.splice(i,1);
                                                        if (!wait.length) whenDone();





                                                        Edit: Updated to work with IE7, IE8, and IE9 (in quirks mode). These IE versions do not fire an onload event, but do for onreadystatechange. IE9 in standards mode fires both (with onreadystatechange for all scripts firing before onload for any).



                                                        Based on this page there may be a small chance that old versions of IE will never send an onreadystatechange event with readyState=='complete'; if this is the case (I could not reproduce this problem) then the above script will fail and your callback will never be invoked.






                                                        share|improve this answer














                                                        If you need to load an arbitrary number of scripts and only proceed when the last one is done, and you cannot use XHR (e.g. due to CORS limitations) you can do the following. It is not synchronous, but does allow a callback to occur exactly when the last file is done loading:



                                                        // Load <script> elements for all uris
                                                        // Invoke the whenDone callback function after the last URI has loaded
                                                        function loadScripts(uris,whenDone)
                                                        if (!uris.length) whenDone && whenDone();
                                                        else
                                                        for (var wait=,i=uris.length;i--;)
                                                        var tag = document.createElement('script');
                                                        tag.type = 'text/javascript';
                                                        tag.src = uris[i];
                                                        if (whenDone)
                                                        wait.push(tag)
                                                        tag.onload = maybeDone;
                                                        tag.onreadystatechange = maybeDone; // For IE8-

                                                        document.body.appendChild(tag);


                                                        function maybeDone() this.readyState==='complete')
                                                        // Pull the tags out based on the actual element in case IE ever
                                                        // intermingles the onload and onreadystatechange handlers for the same
                                                        // script block before notifying for another one.
                                                        for (var i=wait.length;i--;) if (wait[i]==this) wait.splice(i,1);
                                                        if (!wait.length) whenDone();





                                                        Edit: Updated to work with IE7, IE8, and IE9 (in quirks mode). These IE versions do not fire an onload event, but do for onreadystatechange. IE9 in standards mode fires both (with onreadystatechange for all scripts firing before onload for any).



                                                        Based on this page there may be a small chance that old versions of IE will never send an onreadystatechange event with readyState=='complete'; if this is the case (I could not reproduce this problem) then the above script will fail and your callback will never be invoked.







                                                        share|improve this answer














                                                        share|improve this answer



                                                        share|improve this answer








                                                        edited Jun 20 '12 at 19:40

























                                                        answered Jun 20 '12 at 16:12









                                                        Phrogz

                                                        218k73535612




                                                        218k73535612











                                                        • I think there may be some per-browser issues with getting the "load" event reliably (or at all), based on various grumblings I've seen from script loader authors.
                                                          – Pointy
                                                          Jun 20 '12 at 16:14










                                                        • @Pointy Ooh, that's good to know; thanks. I'll have to look into that more.
                                                          – Phrogz
                                                          Jun 20 '12 at 16:16






                                                        • 1




                                                          I'm not very familiar with the issues; I've been looking through the source of LABjs and mostly it's just making me confused. (I picked that one because the author is an acquaintance.)
                                                          – Pointy
                                                          Jun 20 '12 at 16:26










                                                        • @Pointy Thanks to your note I found this page which describes the need to use onreadystatechange for IE. In testing, IE9 in standards mode does not require this, but older versions do. I've updated my answer with code that works in the current versions of all major browsers, and also IE7 and IE8.
                                                          – Phrogz
                                                          Jun 20 '12 at 19:42

















                                                        • I think there may be some per-browser issues with getting the "load" event reliably (or at all), based on various grumblings I've seen from script loader authors.
                                                          – Pointy
                                                          Jun 20 '12 at 16:14










                                                        • @Pointy Ooh, that's good to know; thanks. I'll have to look into that more.
                                                          – Phrogz
                                                          Jun 20 '12 at 16:16






                                                        • 1




                                                          I'm not very familiar with the issues; I've been looking through the source of LABjs and mostly it's just making me confused. (I picked that one because the author is an acquaintance.)
                                                          – Pointy
                                                          Jun 20 '12 at 16:26










                                                        • @Pointy Thanks to your note I found this page which describes the need to use onreadystatechange for IE. In testing, IE9 in standards mode does not require this, but older versions do. I've updated my answer with code that works in the current versions of all major browsers, and also IE7 and IE8.
                                                          – Phrogz
                                                          Jun 20 '12 at 19:42
















                                                        I think there may be some per-browser issues with getting the "load" event reliably (or at all), based on various grumblings I've seen from script loader authors.
                                                        – Pointy
                                                        Jun 20 '12 at 16:14




                                                        I think there may be some per-browser issues with getting the "load" event reliably (or at all), based on various grumblings I've seen from script loader authors.
                                                        – Pointy
                                                        Jun 20 '12 at 16:14












                                                        @Pointy Ooh, that's good to know; thanks. I'll have to look into that more.
                                                        – Phrogz
                                                        Jun 20 '12 at 16:16




                                                        @Pointy Ooh, that's good to know; thanks. I'll have to look into that more.
                                                        – Phrogz
                                                        Jun 20 '12 at 16:16




                                                        1




                                                        1




                                                        I'm not very familiar with the issues; I've been looking through the source of LABjs and mostly it's just making me confused. (I picked that one because the author is an acquaintance.)
                                                        – Pointy
                                                        Jun 20 '12 at 16:26




                                                        I'm not very familiar with the issues; I've been looking through the source of LABjs and mostly it's just making me confused. (I picked that one because the author is an acquaintance.)
                                                        – Pointy
                                                        Jun 20 '12 at 16:26












                                                        @Pointy Thanks to your note I found this page which describes the need to use onreadystatechange for IE. In testing, IE9 in standards mode does not require this, but older versions do. I've updated my answer with code that works in the current versions of all major browsers, and also IE7 and IE8.
                                                        – Phrogz
                                                        Jun 20 '12 at 19:42





                                                        @Pointy Thanks to your note I found this page which describes the need to use onreadystatechange for IE. In testing, IE9 in standards mode does not require this, but older versions do. I've updated my answer with code that works in the current versions of all major browsers, and also IE7 and IE8.
                                                        – Phrogz
                                                        Jun 20 '12 at 19:42











                                                        up vote
                                                        0
                                                        down vote













                                                        You can't and shouldn't perform server operations synchronously for obvious reasons. What you can do, though, is to have an event handler telling you when the script is loaded:



                                                        tag.onreadystatechange = function() if (this.readyState == 'complete' ;

                                                        tag.onload = function(load) /*init code here*/


                                                        onreadystatechange delegation is, from memory, a workaround for IE, which has patchy support for onload.






                                                        share|improve this answer


















                                                        • 1




                                                          Saying 'You can't' is directly wrong as shown by my answer ;)
                                                          – Sean Kinsey
                                                          May 21 '10 at 7:03






                                                        • 1




                                                          I stand corrected.
                                                          – Igor Zevaka
                                                          May 21 '10 at 7:43














                                                        up vote
                                                        0
                                                        down vote













                                                        You can't and shouldn't perform server operations synchronously for obvious reasons. What you can do, though, is to have an event handler telling you when the script is loaded:



                                                        tag.onreadystatechange = function() if (this.readyState == 'complete' ;

                                                        tag.onload = function(load) /*init code here*/


                                                        onreadystatechange delegation is, from memory, a workaround for IE, which has patchy support for onload.






                                                        share|improve this answer


















                                                        • 1




                                                          Saying 'You can't' is directly wrong as shown by my answer ;)
                                                          – Sean Kinsey
                                                          May 21 '10 at 7:03






                                                        • 1




                                                          I stand corrected.
                                                          – Igor Zevaka
                                                          May 21 '10 at 7:43












                                                        up vote
                                                        0
                                                        down vote










                                                        up vote
                                                        0
                                                        down vote









                                                        You can't and shouldn't perform server operations synchronously for obvious reasons. What you can do, though, is to have an event handler telling you when the script is loaded:



                                                        tag.onreadystatechange = function() if (this.readyState == 'complete' ;

                                                        tag.onload = function(load) /*init code here*/


                                                        onreadystatechange delegation is, from memory, a workaround for IE, which has patchy support for onload.






                                                        share|improve this answer














                                                        You can't and shouldn't perform server operations synchronously for obvious reasons. What you can do, though, is to have an event handler telling you when the script is loaded:



                                                        tag.onreadystatechange = function() if (this.readyState == 'complete' ;

                                                        tag.onload = function(load) /*init code here*/


                                                        onreadystatechange delegation is, from memory, a workaround for IE, which has patchy support for onload.







                                                        share|improve this answer














                                                        share|improve this answer



                                                        share|improve this answer








                                                        edited May 21 '10 at 7:42

























                                                        answered May 21 '10 at 4:20









                                                        Igor Zevaka

                                                        52.1k2193118




                                                        52.1k2193118







                                                        • 1




                                                          Saying 'You can't' is directly wrong as shown by my answer ;)
                                                          – Sean Kinsey
                                                          May 21 '10 at 7:03






                                                        • 1




                                                          I stand corrected.
                                                          – Igor Zevaka
                                                          May 21 '10 at 7:43












                                                        • 1




                                                          Saying 'You can't' is directly wrong as shown by my answer ;)
                                                          – Sean Kinsey
                                                          May 21 '10 at 7:03






                                                        • 1




                                                          I stand corrected.
                                                          – Igor Zevaka
                                                          May 21 '10 at 7:43







                                                        1




                                                        1




                                                        Saying 'You can't' is directly wrong as shown by my answer ;)
                                                        – Sean Kinsey
                                                        May 21 '10 at 7:03




                                                        Saying 'You can't' is directly wrong as shown by my answer ;)
                                                        – Sean Kinsey
                                                        May 21 '10 at 7:03




                                                        1




                                                        1




                                                        I stand corrected.
                                                        – Igor Zevaka
                                                        May 21 '10 at 7:43




                                                        I stand corrected.
                                                        – Igor Zevaka
                                                        May 21 '10 at 7:43










                                                        up vote
                                                        0
                                                        down vote













                                                        same as Sean's answer, but instead of creating a script tag, just evaluate it. this ensures that the code is actually ready to use.






                                                        share|improve this answer




















                                                        • Please elaborate. eval() what? The text source of an external script?
                                                          – Steven Vachon
                                                          Dec 29 '13 at 19:18














                                                        up vote
                                                        0
                                                        down vote













                                                        same as Sean's answer, but instead of creating a script tag, just evaluate it. this ensures that the code is actually ready to use.






                                                        share|improve this answer




















                                                        • Please elaborate. eval() what? The text source of an external script?
                                                          – Steven Vachon
                                                          Dec 29 '13 at 19:18












                                                        up vote
                                                        0
                                                        down vote










                                                        up vote
                                                        0
                                                        down vote









                                                        same as Sean's answer, but instead of creating a script tag, just evaluate it. this ensures that the code is actually ready to use.






                                                        share|improve this answer












                                                        same as Sean's answer, but instead of creating a script tag, just evaluate it. this ensures that the code is actually ready to use.







                                                        share|improve this answer












                                                        share|improve this answer



                                                        share|improve this answer










                                                        answered May 21 '12 at 19:23









                                                        Peter Hawkins

                                                        36436




                                                        36436











                                                        • Please elaborate. eval() what? The text source of an external script?
                                                          – Steven Vachon
                                                          Dec 29 '13 at 19:18
















                                                        • Please elaborate. eval() what? The text source of an external script?
                                                          – Steven Vachon
                                                          Dec 29 '13 at 19:18















                                                        Please elaborate. eval() what? The text source of an external script?
                                                        – Steven Vachon
                                                        Dec 29 '13 at 19:18




                                                        Please elaborate. eval() what? The text source of an external script?
                                                        – Steven Vachon
                                                        Dec 29 '13 at 19:18










                                                        up vote
                                                        0
                                                        down vote













                                                        My strategy, classic example when load jQuery UI, i hope this can help you






                                                        ( function( tools, libs )

                                                        // Iterator
                                                        var require = function( scripts, onEnd );

                                                        // Install all scripts with a copy of scripts
                                                        require( libs.slice(), function()

                                                        alert( "Enjoy :)" );

                                                        );

                                                        // Timeout information
                                                        var ti = setTimeout( function() !window.jQuery.ui )alert( "Timeout !" );

                                                        clearTimeout( ti );

                                                        , 5000 );

                                                        )(

                                                        // Tools

                                                        addEvent : function( evnt, elem, func )

                                                        try

                                                        if( elem.addEventListener )

                                                        elem.addEventListener( evnt, func, false );

                                                        else if( elem.attachEvent )

                                                        var r = elem.attachEvent( "on" + evnt, func );



                                                        return true;

                                                        catch( e )

                                                        return false;





                                                        ,
                                                        [ // Scripts

                                                        "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js",
                                                        "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"

                                                        ]

                                                        );








                                                        share|improve this answer
























                                                          up vote
                                                          0
                                                          down vote













                                                          My strategy, classic example when load jQuery UI, i hope this can help you






                                                          ( function( tools, libs )

                                                          // Iterator
                                                          var require = function( scripts, onEnd );

                                                          // Install all scripts with a copy of scripts
                                                          require( libs.slice(), function()

                                                          alert( "Enjoy :)" );

                                                          );

                                                          // Timeout information
                                                          var ti = setTimeout( function() !window.jQuery.ui )alert( "Timeout !" );

                                                          clearTimeout( ti );

                                                          , 5000 );

                                                          )(

                                                          // Tools

                                                          addEvent : function( evnt, elem, func )

                                                          try

                                                          if( elem.addEventListener )

                                                          elem.addEventListener( evnt, func, false );

                                                          else if( elem.attachEvent )

                                                          var r = elem.attachEvent( "on" + evnt, func );



                                                          return true;

                                                          catch( e )

                                                          return false;





                                                          ,
                                                          [ // Scripts

                                                          "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js",
                                                          "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"

                                                          ]

                                                          );








                                                          share|improve this answer






















                                                            up vote
                                                            0
                                                            down vote










                                                            up vote
                                                            0
                                                            down vote









                                                            My strategy, classic example when load jQuery UI, i hope this can help you






                                                            ( function( tools, libs )

                                                            // Iterator
                                                            var require = function( scripts, onEnd );

                                                            // Install all scripts with a copy of scripts
                                                            require( libs.slice(), function()

                                                            alert( "Enjoy :)" );

                                                            );

                                                            // Timeout information
                                                            var ti = setTimeout( function() !window.jQuery.ui )alert( "Timeout !" );

                                                            clearTimeout( ti );

                                                            , 5000 );

                                                            )(

                                                            // Tools

                                                            addEvent : function( evnt, elem, func )

                                                            try

                                                            if( elem.addEventListener )

                                                            elem.addEventListener( evnt, func, false );

                                                            else if( elem.attachEvent )

                                                            var r = elem.attachEvent( "on" + evnt, func );



                                                            return true;

                                                            catch( e )

                                                            return false;





                                                            ,
                                                            [ // Scripts

                                                            "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js",
                                                            "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"

                                                            ]

                                                            );








                                                            share|improve this answer












                                                            My strategy, classic example when load jQuery UI, i hope this can help you






                                                            ( function( tools, libs )

                                                            // Iterator
                                                            var require = function( scripts, onEnd );

                                                            // Install all scripts with a copy of scripts
                                                            require( libs.slice(), function()

                                                            alert( "Enjoy :)" );

                                                            );

                                                            // Timeout information
                                                            var ti = setTimeout( function() !window.jQuery.ui )alert( "Timeout !" );

                                                            clearTimeout( ti );

                                                            , 5000 );

                                                            )(

                                                            // Tools

                                                            addEvent : function( evnt, elem, func )

                                                            try

                                                            if( elem.addEventListener )

                                                            elem.addEventListener( evnt, func, false );

                                                            else if( elem.attachEvent )

                                                            var r = elem.attachEvent( "on" + evnt, func );



                                                            return true;

                                                            catch( e )

                                                            return false;





                                                            ,
                                                            [ // Scripts

                                                            "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js",
                                                            "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"

                                                            ]

                                                            );








                                                            ( function( tools, libs )

                                                            // Iterator
                                                            var require = function( scripts, onEnd );

                                                            // Install all scripts with a copy of scripts
                                                            require( libs.slice(), function()

                                                            alert( "Enjoy :)" );

                                                            );

                                                            // Timeout information
                                                            var ti = setTimeout( function() !window.jQuery.ui )alert( "Timeout !" );

                                                            clearTimeout( ti );

                                                            , 5000 );

                                                            )(

                                                            // Tools

                                                            addEvent : function( evnt, elem, func )

                                                            try

                                                            if( elem.addEventListener )

                                                            elem.addEventListener( evnt, func, false );

                                                            else if( elem.attachEvent )

                                                            var r = elem.attachEvent( "on" + evnt, func );



                                                            return true;

                                                            catch( e )

                                                            return false;





                                                            ,
                                                            [ // Scripts

                                                            "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js",
                                                            "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"

                                                            ]

                                                            );





                                                            ( function( tools, libs )

                                                            // Iterator
                                                            var require = function( scripts, onEnd );

                                                            // Install all scripts with a copy of scripts
                                                            require( libs.slice(), function()

                                                            alert( "Enjoy :)" );

                                                            );

                                                            // Timeout information
                                                            var ti = setTimeout( function() !window.jQuery.ui )alert( "Timeout !" );

                                                            clearTimeout( ti );

                                                            , 5000 );

                                                            )(

                                                            // Tools

                                                            addEvent : function( evnt, elem, func )

                                                            try

                                                            if( elem.addEventListener )

                                                            elem.addEventListener( evnt, func, false );

                                                            else if( elem.attachEvent )

                                                            var r = elem.attachEvent( "on" + evnt, func );



                                                            return true;

                                                            catch( e )

                                                            return false;





                                                            ,
                                                            [ // Scripts

                                                            "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js",
                                                            "https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"

                                                            ]

                                                            );






                                                            share|improve this answer












                                                            share|improve this answer



                                                            share|improve this answer










                                                            answered Aug 26 '15 at 11:01









                                                            Leonardo Ciaccio

                                                            695711




                                                            695711




















                                                                up vote
                                                                0
                                                                down vote













                                                                When using Angular you can take advantage of the fact that every Provider is instantiated before other services are instantiated. You can combine this fact with using xhr and the eval() as mentioned by @Neil. The code would be following:



                                                                app.provider('SomeScriptSyncLoader', function() 

                                                                var resourceUrl = 'http://some/script.js';
                                                                var dummy = ;

                                                                this.$get = function()

                                                                var q = jQuery.ajax(
                                                                type: 'GET', url: resourceUrl, cache: false, async: false
                                                                );

                                                                if (q.status === 200)
                                                                eval(q.responseText); // execute some script synchronously as inline script - eval forces sync processing

                                                                return dummy;
                                                                ;
                                                                );


                                                                To force the Provider to be inialized you need to inject it in at least one other directive/service. Preferably this would be the service which takes advantage of the code loaded by script.



                                                                app.directive('myDirective', ['SomeScriptSyncLoader', function(someScriptSyncLoader) 

                                                                return
                                                                restrict: 'E',
                                                                link: function(scope, element, attrs)
                                                                // some ode
                                                                ,
                                                                template: "this is my template"
                                                                ;
                                                                ]);





                                                                share|improve this answer
























                                                                  up vote
                                                                  0
                                                                  down vote













                                                                  When using Angular you can take advantage of the fact that every Provider is instantiated before other services are instantiated. You can combine this fact with using xhr and the eval() as mentioned by @Neil. The code would be following:



                                                                  app.provider('SomeScriptSyncLoader', function() 

                                                                  var resourceUrl = 'http://some/script.js';
                                                                  var dummy = ;

                                                                  this.$get = function()

                                                                  var q = jQuery.ajax(
                                                                  type: 'GET', url: resourceUrl, cache: false, async: false
                                                                  );

                                                                  if (q.status === 200)
                                                                  eval(q.responseText); // execute some script synchronously as inline script - eval forces sync processing

                                                                  return dummy;
                                                                  ;
                                                                  );


                                                                  To force the Provider to be inialized you need to inject it in at least one other directive/service. Preferably this would be the service which takes advantage of the code loaded by script.



                                                                  app.directive('myDirective', ['SomeScriptSyncLoader', function(someScriptSyncLoader) 

                                                                  return
                                                                  restrict: 'E',
                                                                  link: function(scope, element, attrs)
                                                                  // some ode
                                                                  ,
                                                                  template: "this is my template"
                                                                  ;
                                                                  ]);





                                                                  share|improve this answer






















                                                                    up vote
                                                                    0
                                                                    down vote










                                                                    up vote
                                                                    0
                                                                    down vote









                                                                    When using Angular you can take advantage of the fact that every Provider is instantiated before other services are instantiated. You can combine this fact with using xhr and the eval() as mentioned by @Neil. The code would be following:



                                                                    app.provider('SomeScriptSyncLoader', function() 

                                                                    var resourceUrl = 'http://some/script.js';
                                                                    var dummy = ;

                                                                    this.$get = function()

                                                                    var q = jQuery.ajax(
                                                                    type: 'GET', url: resourceUrl, cache: false, async: false
                                                                    );

                                                                    if (q.status === 200)
                                                                    eval(q.responseText); // execute some script synchronously as inline script - eval forces sync processing

                                                                    return dummy;
                                                                    ;
                                                                    );


                                                                    To force the Provider to be inialized you need to inject it in at least one other directive/service. Preferably this would be the service which takes advantage of the code loaded by script.



                                                                    app.directive('myDirective', ['SomeScriptSyncLoader', function(someScriptSyncLoader) 

                                                                    return
                                                                    restrict: 'E',
                                                                    link: function(scope, element, attrs)
                                                                    // some ode
                                                                    ,
                                                                    template: "this is my template"
                                                                    ;
                                                                    ]);





                                                                    share|improve this answer












                                                                    When using Angular you can take advantage of the fact that every Provider is instantiated before other services are instantiated. You can combine this fact with using xhr and the eval() as mentioned by @Neil. The code would be following:



                                                                    app.provider('SomeScriptSyncLoader', function() 

                                                                    var resourceUrl = 'http://some/script.js';
                                                                    var dummy = ;

                                                                    this.$get = function()

                                                                    var q = jQuery.ajax(
                                                                    type: 'GET', url: resourceUrl, cache: false, async: false
                                                                    );

                                                                    if (q.status === 200)
                                                                    eval(q.responseText); // execute some script synchronously as inline script - eval forces sync processing

                                                                    return dummy;
                                                                    ;
                                                                    );


                                                                    To force the Provider to be inialized you need to inject it in at least one other directive/service. Preferably this would be the service which takes advantage of the code loaded by script.



                                                                    app.directive('myDirective', ['SomeScriptSyncLoader', function(someScriptSyncLoader) 

                                                                    return
                                                                    restrict: 'E',
                                                                    link: function(scope, element, attrs)
                                                                    // some ode
                                                                    ,
                                                                    template: "this is my template"
                                                                    ;
                                                                    ]);






                                                                    share|improve this answer












                                                                    share|improve this answer



                                                                    share|improve this answer










                                                                    answered Jan 26 '16 at 12:36









                                                                    walkeros

                                                                    2,2661627




                                                                    2,2661627




















                                                                        up vote
                                                                        0
                                                                        down vote













                                                                        I know this is an old question, but maybe someone else read this and find it useful !
                                                                        Just created a new components uses ES6 to load scripts dynamically in synchronous way.
                                                                        The Project details and source code are on GitHub https://github.com/amgadfahmi/scripty






                                                                        share|improve this answer
























                                                                          up vote
                                                                          0
                                                                          down vote













                                                                          I know this is an old question, but maybe someone else read this and find it useful !
                                                                          Just created a new components uses ES6 to load scripts dynamically in synchronous way.
                                                                          The Project details and source code are on GitHub https://github.com/amgadfahmi/scripty






                                                                          share|improve this answer






















                                                                            up vote
                                                                            0
                                                                            down vote










                                                                            up vote
                                                                            0
                                                                            down vote









                                                                            I know this is an old question, but maybe someone else read this and find it useful !
                                                                            Just created a new components uses ES6 to load scripts dynamically in synchronous way.
                                                                            The Project details and source code are on GitHub https://github.com/amgadfahmi/scripty






                                                                            share|improve this answer












                                                                            I know this is an old question, but maybe someone else read this and find it useful !
                                                                            Just created a new components uses ES6 to load scripts dynamically in synchronous way.
                                                                            The Project details and source code are on GitHub https://github.com/amgadfahmi/scripty







                                                                            share|improve this answer












                                                                            share|improve this answer



                                                                            share|improve this answer










                                                                            answered Oct 20 '16 at 14:49









                                                                            Amgad Fahmi

                                                                            2,34831417




                                                                            2,34831417




















                                                                                up vote
                                                                                0
                                                                                down vote













                                                                                I may be late to answering this question.



                                                                                My current solution is to recursively add <script> tags such that the addition of the subsequent script is in the callback of its predecessor. It assumes that each function contains one function and that function is the same as the file name (minus the extension). This probably isn't the best way to do things, but it works ok.



                                                                                Code to consider



                                                                                Code directory structure:



                                                                                - directory
                                                                                ---- index.html
                                                                                ---- bundle.js
                                                                                ---- test_module/
                                                                                -------- a.js
                                                                                -------- b.js
                                                                                -------- log_num.js
                                                                                -------- many_parameters.js


                                                                                index.html



                                                                                <head>
                                                                                <script src="bundle.js"></script>
                                                                                </head>


                                                                                bundle.js



                                                                                // Give JS arrays the .empty() function prototype
                                                                                if (!Array.prototype.empty)
                                                                                Array.prototype.empty = function()
                                                                                return this.length == 0;
                                                                                ;
                                                                                ;

                                                                                function bundle(module_object, list_of_files, directory="")
                                                                                if (!list_of_files.empty())
                                                                                var current_file = list_of_files.pop()
                                                                                var [function_name, extension] = current_file.split(".")
                                                                                var new_script = document.createElement("script")
                                                                                document.head.appendChild(new_script)

                                                                                new_script.src = directory + current_file

                                                                                new_script.onload = function()
                                                                                module_object[function_name] = eval(function_name)
                                                                                bundle(module_object, list_of_files, directory)
                                                                                /*
                                                                                nullify the function in the global namespace as - assumed - last
                                                                                reference to this function garbage collection will remove it. Thus modules
                                                                                assembled by this function - bundle(obj, files, dir) - must be called
                                                                                FIRST, else one risks overwritting a funciton in the global namespace and
                                                                                then deleting it
                                                                                */
                                                                                eval(function_name + "= undefined")




                                                                                var test_module =
                                                                                bundle(test_module, ["a.js", "b.js", "log_num.js", "many_parameters.js"], "test_module/")


                                                                                a.js



                                                                                function a() 
                                                                                console.log("a")



                                                                                b.js



                                                                                function b() 
                                                                                console.log("b")



                                                                                log_num.js



                                                                                // it works with parameters too
                                                                                function log_num(num)
                                                                                console.log(num)



                                                                                many_parameters.js



                                                                                function many_parameters(a, b, c) 
                                                                                var calc = a - b * c
                                                                                console.log(calc)






                                                                                share|improve this answer
























                                                                                  up vote
                                                                                  0
                                                                                  down vote













                                                                                  I may be late to answering this question.



                                                                                  My current solution is to recursively add <script> tags such that the addition of the subsequent script is in the callback of its predecessor. It assumes that each function contains one function and that function is the same as the file name (minus the extension). This probably isn't the best way to do things, but it works ok.



                                                                                  Code to consider



                                                                                  Code directory structure:



                                                                                  - directory
                                                                                  ---- index.html
                                                                                  ---- bundle.js
                                                                                  ---- test_module/
                                                                                  -------- a.js
                                                                                  -------- b.js
                                                                                  -------- log_num.js
                                                                                  -------- many_parameters.js


                                                                                  index.html



                                                                                  <head>
                                                                                  <script src="bundle.js"></script>
                                                                                  </head>


                                                                                  bundle.js



                                                                                  // Give JS arrays the .empty() function prototype
                                                                                  if (!Array.prototype.empty)
                                                                                  Array.prototype.empty = function()
                                                                                  return this.length == 0;
                                                                                  ;
                                                                                  ;

                                                                                  function bundle(module_object, list_of_files, directory="")
                                                                                  if (!list_of_files.empty())
                                                                                  var current_file = list_of_files.pop()
                                                                                  var [function_name, extension] = current_file.split(".")
                                                                                  var new_script = document.createElement("script")
                                                                                  document.head.appendChild(new_script)

                                                                                  new_script.src = directory + current_file

                                                                                  new_script.onload = function()
                                                                                  module_object[function_name] = eval(function_name)
                                                                                  bundle(module_object, list_of_files, directory)
                                                                                  /*
                                                                                  nullify the function in the global namespace as - assumed - last
                                                                                  reference to this function garbage collection will remove it. Thus modules
                                                                                  assembled by this function - bundle(obj, files, dir) - must be called
                                                                                  FIRST, else one risks overwritting a funciton in the global namespace and
                                                                                  then deleting it
                                                                                  */
                                                                                  eval(function_name + "= undefined")




                                                                                  var test_module =
                                                                                  bundle(test_module, ["a.js", "b.js", "log_num.js", "many_parameters.js"], "test_module/")


                                                                                  a.js



                                                                                  function a() 
                                                                                  console.log("a")



                                                                                  b.js



                                                                                  function b() 
                                                                                  console.log("b")



                                                                                  log_num.js



                                                                                  // it works with parameters too
                                                                                  function log_num(num)
                                                                                  console.log(num)



                                                                                  many_parameters.js



                                                                                  function many_parameters(a, b, c) 
                                                                                  var calc = a - b * c
                                                                                  console.log(calc)






                                                                                  share|improve this answer






















                                                                                    up vote
                                                                                    0
                                                                                    down vote










                                                                                    up vote
                                                                                    0
                                                                                    down vote









                                                                                    I may be late to answering this question.



                                                                                    My current solution is to recursively add <script> tags such that the addition of the subsequent script is in the callback of its predecessor. It assumes that each function contains one function and that function is the same as the file name (minus the extension). This probably isn't the best way to do things, but it works ok.



                                                                                    Code to consider



                                                                                    Code directory structure:



                                                                                    - directory
                                                                                    ---- index.html
                                                                                    ---- bundle.js
                                                                                    ---- test_module/
                                                                                    -------- a.js
                                                                                    -------- b.js
                                                                                    -------- log_num.js
                                                                                    -------- many_parameters.js


                                                                                    index.html



                                                                                    <head>
                                                                                    <script src="bundle.js"></script>
                                                                                    </head>


                                                                                    bundle.js



                                                                                    // Give JS arrays the .empty() function prototype
                                                                                    if (!Array.prototype.empty)
                                                                                    Array.prototype.empty = function()
                                                                                    return this.length == 0;
                                                                                    ;
                                                                                    ;

                                                                                    function bundle(module_object, list_of_files, directory="")
                                                                                    if (!list_of_files.empty())
                                                                                    var current_file = list_of_files.pop()
                                                                                    var [function_name, extension] = current_file.split(".")
                                                                                    var new_script = document.createElement("script")
                                                                                    document.head.appendChild(new_script)

                                                                                    new_script.src = directory + current_file

                                                                                    new_script.onload = function()
                                                                                    module_object[function_name] = eval(function_name)
                                                                                    bundle(module_object, list_of_files, directory)
                                                                                    /*
                                                                                    nullify the function in the global namespace as - assumed - last
                                                                                    reference to this function garbage collection will remove it. Thus modules
                                                                                    assembled by this function - bundle(obj, files, dir) - must be called
                                                                                    FIRST, else one risks overwritting a funciton in the global namespace and
                                                                                    then deleting it
                                                                                    */
                                                                                    eval(function_name + "= undefined")




                                                                                    var test_module =
                                                                                    bundle(test_module, ["a.js", "b.js", "log_num.js", "many_parameters.js"], "test_module/")


                                                                                    a.js



                                                                                    function a() 
                                                                                    console.log("a")



                                                                                    b.js



                                                                                    function b() 
                                                                                    console.log("b")



                                                                                    log_num.js



                                                                                    // it works with parameters too
                                                                                    function log_num(num)
                                                                                    console.log(num)



                                                                                    many_parameters.js



                                                                                    function many_parameters(a, b, c) 
                                                                                    var calc = a - b * c
                                                                                    console.log(calc)






                                                                                    share|improve this answer












                                                                                    I may be late to answering this question.



                                                                                    My current solution is to recursively add <script> tags such that the addition of the subsequent script is in the callback of its predecessor. It assumes that each function contains one function and that function is the same as the file name (minus the extension). This probably isn't the best way to do things, but it works ok.



                                                                                    Code to consider



                                                                                    Code directory structure:



                                                                                    - directory
                                                                                    ---- index.html
                                                                                    ---- bundle.js
                                                                                    ---- test_module/
                                                                                    -------- a.js
                                                                                    -------- b.js
                                                                                    -------- log_num.js
                                                                                    -------- many_parameters.js


                                                                                    index.html



                                                                                    <head>
                                                                                    <script src="bundle.js"></script>
                                                                                    </head>


                                                                                    bundle.js



                                                                                    // Give JS arrays the .empty() function prototype
                                                                                    if (!Array.prototype.empty)
                                                                                    Array.prototype.empty = function()
                                                                                    return this.length == 0;
                                                                                    ;
                                                                                    ;

                                                                                    function bundle(module_object, list_of_files, directory="")
                                                                                    if (!list_of_files.empty())
                                                                                    var current_file = list_of_files.pop()
                                                                                    var [function_name, extension] = current_file.split(".")
                                                                                    var new_script = document.createElement("script")
                                                                                    document.head.appendChild(new_script)

                                                                                    new_script.src = directory + current_file

                                                                                    new_script.onload = function()
                                                                                    module_object[function_name] = eval(function_name)
                                                                                    bundle(module_object, list_of_files, directory)
                                                                                    /*
                                                                                    nullify the function in the global namespace as - assumed - last
                                                                                    reference to this function garbage collection will remove it. Thus modules
                                                                                    assembled by this function - bundle(obj, files, dir) - must be called
                                                                                    FIRST, else one risks overwritting a funciton in the global namespace and
                                                                                    then deleting it
                                                                                    */
                                                                                    eval(function_name + "= undefined")




                                                                                    var test_module =
                                                                                    bundle(test_module, ["a.js", "b.js", "log_num.js", "many_parameters.js"], "test_module/")


                                                                                    a.js



                                                                                    function a() 
                                                                                    console.log("a")



                                                                                    b.js



                                                                                    function b() 
                                                                                    console.log("b")



                                                                                    log_num.js



                                                                                    // it works with parameters too
                                                                                    function log_num(num)
                                                                                    console.log(num)



                                                                                    many_parameters.js



                                                                                    function many_parameters(a, b, c) 
                                                                                    var calc = a - b * c
                                                                                    console.log(calc)







                                                                                    share|improve this answer












                                                                                    share|improve this answer



                                                                                    share|improve this answer










                                                                                    answered May 9 '17 at 18:32









                                                                                    SumNeuron

                                                                                    1,004723




                                                                                    1,004723




















                                                                                        up vote
                                                                                        0
                                                                                        down vote













                                                                                        There actually is a way to load a list of scripts and execute them synchronously. You need to insert each script tag into the DOM, explicitly setting its async attribute to false:



                                                                                        script.async = false;


                                                                                        Scripts that have been injected into the DOM are executed asynchronously by default, so you have to set the async attribute to false manually to work around this.



                                                                                        Example



                                                                                        <script>
                                                                                        (function()
                                                                                        var scriptNames = [
                                                                                        "https://code.jquery.com/jquery.min.js",
                                                                                        "example.js"
                                                                                        ];
                                                                                        for (var i = 0; i < scriptNames.length; i++)
                                                                                        var script = document.createElement('script');
                                                                                        script.src = scriptNames[i];
                                                                                        script.async = false; // This is required for synchronous execution
                                                                                        document.head.appendChild(script);

                                                                                        // jquery.min.js and example.js will be run in order and synchronously
                                                                                        )();
                                                                                        </script>

                                                                                        <!-- Gotcha: these two script tags may still be run before `jquery.min.js`
                                                                                        and `example.js` -->
                                                                                        <script src="example2.js"></script>
                                                                                        <script>/* ... */<script>


                                                                                        References



                                                                                        • There is a great article by Jake Archibald of Google about this called Deep dive into the murky waters of script loading.

                                                                                        • The WHATWG spec on the tag is a good and thorough description of how tags are loaded.





                                                                                        share|improve this answer


























                                                                                          up vote
                                                                                          0
                                                                                          down vote













                                                                                          There actually is a way to load a list of scripts and execute them synchronously. You need to insert each script tag into the DOM, explicitly setting its async attribute to false:



                                                                                          script.async = false;


                                                                                          Scripts that have been injected into the DOM are executed asynchronously by default, so you have to set the async attribute to false manually to work around this.



                                                                                          Example



                                                                                          <script>
                                                                                          (function()
                                                                                          var scriptNames = [
                                                                                          "https://code.jquery.com/jquery.min.js",
                                                                                          "example.js"
                                                                                          ];
                                                                                          for (var i = 0; i < scriptNames.length; i++)
                                                                                          var script = document.createElement('script');
                                                                                          script.src = scriptNames[i];
                                                                                          script.async = false; // This is required for synchronous execution
                                                                                          document.head.appendChild(script);

                                                                                          // jquery.min.js and example.js will be run in order and synchronously
                                                                                          )();
                                                                                          </script>

                                                                                          <!-- Gotcha: these two script tags may still be run before `jquery.min.js`
                                                                                          and `example.js` -->
                                                                                          <script src="example2.js"></script>
                                                                                          <script>/* ... */<script>


                                                                                          References



                                                                                          • There is a great article by Jake Archibald of Google about this called Deep dive into the murky waters of script loading.

                                                                                          • The WHATWG spec on the tag is a good and thorough description of how tags are loaded.





                                                                                          share|improve this answer
























                                                                                            up vote
                                                                                            0
                                                                                            down vote










                                                                                            up vote
                                                                                            0
                                                                                            down vote









                                                                                            There actually is a way to load a list of scripts and execute them synchronously. You need to insert each script tag into the DOM, explicitly setting its async attribute to false:



                                                                                            script.async = false;


                                                                                            Scripts that have been injected into the DOM are executed asynchronously by default, so you have to set the async attribute to false manually to work around this.



                                                                                            Example



                                                                                            <script>
                                                                                            (function()
                                                                                            var scriptNames = [
                                                                                            "https://code.jquery.com/jquery.min.js",
                                                                                            "example.js"
                                                                                            ];
                                                                                            for (var i = 0; i < scriptNames.length; i++)
                                                                                            var script = document.createElement('script');
                                                                                            script.src = scriptNames[i];
                                                                                            script.async = false; // This is required for synchronous execution
                                                                                            document.head.appendChild(script);

                                                                                            // jquery.min.js and example.js will be run in order and synchronously
                                                                                            )();
                                                                                            </script>

                                                                                            <!-- Gotcha: these two script tags may still be run before `jquery.min.js`
                                                                                            and `example.js` -->
                                                                                            <script src="example2.js"></script>
                                                                                            <script>/* ... */<script>


                                                                                            References



                                                                                            • There is a great article by Jake Archibald of Google about this called Deep dive into the murky waters of script loading.

                                                                                            • The WHATWG spec on the tag is a good and thorough description of how tags are loaded.





                                                                                            share|improve this answer














                                                                                            There actually is a way to load a list of scripts and execute them synchronously. You need to insert each script tag into the DOM, explicitly setting its async attribute to false:



                                                                                            script.async = false;


                                                                                            Scripts that have been injected into the DOM are executed asynchronously by default, so you have to set the async attribute to false manually to work around this.



                                                                                            Example



                                                                                            <script>
                                                                                            (function()
                                                                                            var scriptNames = [
                                                                                            "https://code.jquery.com/jquery.min.js",
                                                                                            "example.js"
                                                                                            ];
                                                                                            for (var i = 0; i < scriptNames.length; i++)
                                                                                            var script = document.createElement('script');
                                                                                            script.src = scriptNames[i];
                                                                                            script.async = false; // This is required for synchronous execution
                                                                                            document.head.appendChild(script);

                                                                                            // jquery.min.js and example.js will be run in order and synchronously
                                                                                            )();
                                                                                            </script>

                                                                                            <!-- Gotcha: these two script tags may still be run before `jquery.min.js`
                                                                                            and `example.js` -->
                                                                                            <script src="example2.js"></script>
                                                                                            <script>/* ... */<script>


                                                                                            References



                                                                                            • There is a great article by Jake Archibald of Google about this called Deep dive into the murky waters of script loading.

                                                                                            • The WHATWG spec on the tag is a good and thorough description of how tags are loaded.






                                                                                            share|improve this answer














                                                                                            share|improve this answer



                                                                                            share|improve this answer








                                                                                            edited Jul 12 '17 at 11:39

























                                                                                            answered Jul 11 '17 at 10:51









                                                                                            Flimm

                                                                                            48.8k23130152




                                                                                            48.8k23130152




















                                                                                                up vote
                                                                                                0
                                                                                                down vote













                                                                                                the accepted answer is not correct:



                                                                                                the script.async = false; directive only means that html parsing will be paused during script execution. this does not guarantee in which order javascript code will run. see https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/



                                                                                                the easiest and most elegant solution which was yet to be mentioned here is using promises, like so:



                                                                                                 function loadScript(url) 
                                                                                                return new Promise((resolve, reject) =>
                                                                                                var script = document.createElement('script')
                                                                                                script.src = url
                                                                                                script.onload = () =>
                                                                                                resolve()

                                                                                                script.onerror = () =>
                                                                                                reject('cannot load script '+ url)

                                                                                                document.body.appendChild(script)
                                                                                                )



                                                                                                and then when you want to execute scripts in order:



                                                                                                 loadScript('myfirstscript.js').then(() => 
                                                                                                console.log('first script ran');
                                                                                                loadScript('index.js').then(() =>
                                                                                                console.log('second script ran');
                                                                                                )
                                                                                                )





                                                                                                share|improve this answer
























                                                                                                  up vote
                                                                                                  0
                                                                                                  down vote













                                                                                                  the accepted answer is not correct:



                                                                                                  the script.async = false; directive only means that html parsing will be paused during script execution. this does not guarantee in which order javascript code will run. see https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/



                                                                                                  the easiest and most elegant solution which was yet to be mentioned here is using promises, like so:



                                                                                                   function loadScript(url) 
                                                                                                  return new Promise((resolve, reject) =>
                                                                                                  var script = document.createElement('script')
                                                                                                  script.src = url
                                                                                                  script.onload = () =>
                                                                                                  resolve()

                                                                                                  script.onerror = () =>
                                                                                                  reject('cannot load script '+ url)

                                                                                                  document.body.appendChild(script)
                                                                                                  )



                                                                                                  and then when you want to execute scripts in order:



                                                                                                   loadScript('myfirstscript.js').then(() => 
                                                                                                  console.log('first script ran');
                                                                                                  loadScript('index.js').then(() =>
                                                                                                  console.log('second script ran');
                                                                                                  )
                                                                                                  )





                                                                                                  share|improve this answer






















                                                                                                    up vote
                                                                                                    0
                                                                                                    down vote










                                                                                                    up vote
                                                                                                    0
                                                                                                    down vote









                                                                                                    the accepted answer is not correct:



                                                                                                    the script.async = false; directive only means that html parsing will be paused during script execution. this does not guarantee in which order javascript code will run. see https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/



                                                                                                    the easiest and most elegant solution which was yet to be mentioned here is using promises, like so:



                                                                                                     function loadScript(url) 
                                                                                                    return new Promise((resolve, reject) =>
                                                                                                    var script = document.createElement('script')
                                                                                                    script.src = url
                                                                                                    script.onload = () =>
                                                                                                    resolve()

                                                                                                    script.onerror = () =>
                                                                                                    reject('cannot load script '+ url)

                                                                                                    document.body.appendChild(script)
                                                                                                    )



                                                                                                    and then when you want to execute scripts in order:



                                                                                                     loadScript('myfirstscript.js').then(() => 
                                                                                                    console.log('first script ran');
                                                                                                    loadScript('index.js').then(() =>
                                                                                                    console.log('second script ran');
                                                                                                    )
                                                                                                    )





                                                                                                    share|improve this answer












                                                                                                    the accepted answer is not correct:



                                                                                                    the script.async = false; directive only means that html parsing will be paused during script execution. this does not guarantee in which order javascript code will run. see https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/loading-third-party-javascript/



                                                                                                    the easiest and most elegant solution which was yet to be mentioned here is using promises, like so:



                                                                                                     function loadScript(url) 
                                                                                                    return new Promise((resolve, reject) =>
                                                                                                    var script = document.createElement('script')
                                                                                                    script.src = url
                                                                                                    script.onload = () =>
                                                                                                    resolve()

                                                                                                    script.onerror = () =>
                                                                                                    reject('cannot load script '+ url)

                                                                                                    document.body.appendChild(script)
                                                                                                    )



                                                                                                    and then when you want to execute scripts in order:



                                                                                                     loadScript('myfirstscript.js').then(() => 
                                                                                                    console.log('first script ran');
                                                                                                    loadScript('index.js').then(() =>
                                                                                                    console.log('second script ran');
                                                                                                    )
                                                                                                    )






                                                                                                    share|improve this answer












                                                                                                    share|improve this answer



                                                                                                    share|improve this answer










                                                                                                    answered Sep 20 at 8:53









                                                                                                    Nir O.

                                                                                                    85411123




                                                                                                    85411123




















                                                                                                        up vote
                                                                                                        -1
                                                                                                        down vote













                                                                                                        I use jquery load method applied to div element. something like



                                                                                                        <div id="js">
                                                                                                        <!-- script will be inserted here -->
                                                                                                        </div>

                                                                                                        ...

                                                                                                        $("#js").load("path", function() alert("callback!" );


                                                                                                        You can load scripts several times and each time one script will completely replace the one loaded earlier






                                                                                                        share|improve this answer
























                                                                                                          up vote
                                                                                                          -1
                                                                                                          down vote













                                                                                                          I use jquery load method applied to div element. something like



                                                                                                          <div id="js">
                                                                                                          <!-- script will be inserted here -->
                                                                                                          </div>

                                                                                                          ...

                                                                                                          $("#js").load("path", function() alert("callback!" );


                                                                                                          You can load scripts several times and each time one script will completely replace the one loaded earlier






                                                                                                          share|improve this answer






















                                                                                                            up vote
                                                                                                            -1
                                                                                                            down vote










                                                                                                            up vote
                                                                                                            -1
                                                                                                            down vote









                                                                                                            I use jquery load method applied to div element. something like



                                                                                                            <div id="js">
                                                                                                            <!-- script will be inserted here -->
                                                                                                            </div>

                                                                                                            ...

                                                                                                            $("#js").load("path", function() alert("callback!" );


                                                                                                            You can load scripts several times and each time one script will completely replace the one loaded earlier






                                                                                                            share|improve this answer












                                                                                                            I use jquery load method applied to div element. something like



                                                                                                            <div id="js">
                                                                                                            <!-- script will be inserted here -->
                                                                                                            </div>

                                                                                                            ...

                                                                                                            $("#js").load("path", function() alert("callback!" );


                                                                                                            You can load scripts several times and each time one script will completely replace the one loaded earlier







                                                                                                            share|improve this answer












                                                                                                            share|improve this answer



                                                                                                            share|improve this answer










                                                                                                            answered May 21 '10 at 7:07









                                                                                                            Andrew Florko

                                                                                                            4,149948100




                                                                                                            4,149948100



























                                                                                                                 

                                                                                                                draft saved


                                                                                                                draft discarded















































                                                                                                                 


                                                                                                                draft saved


                                                                                                                draft discarded














                                                                                                                StackExchange.ready(
                                                                                                                function ()
                                                                                                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2879509%2fdynamically-loading-javascript-synchronously%23new-answer', 'question_page');

                                                                                                                );

                                                                                                                Post as a guest














































































                                                                                                                Popular posts from this blog

                                                                                                                Top Tejano songwriter Luis Silva dead of heart attack at 64

                                                                                                                政党

                                                                                                                天津地下鉄3号線