简体   繁体   中英

JS files out of order

I'm having a very frustrating problem with my javascript files. I have one global namespace that contains a page_data, utilities, modules etc namespace.

My directories look like this: /utilities/single_utility.js /modules/module.js etc tec

Anyways, I load the utilities before the modules, (which use the utilities) but keep getting problems.

My loader script looks like this (its wrapped in an SEAF):

    for (var index in file_list) {

    var url = file_list[index];
    var new_script = document.createElement('script');

    new_script.setAttribute("type", "text/javascript");
    new_script.setAttribute("src", url);

    element.appendChild(new_script);
}

Project is my global namespace, that holds all of these other namespaces. But when I try to reference a utility in one of my modules, with Project.utilities.session.exist() etc, it will sometimes throw an error that Project can't be found?

How can I fix this to make sure my files are loading properly or am I doing something else wrong?

Using async = false should protect your load order.

This is a quick snippet I use to load and maintain order.

var loadScript = function( url ) {
    if (url) {
        var doc = document,
        t = doc.createElement("script"),
        s = doc.getElementsByTagName("script")[0];
        t.type = "text/javascript";
        // Keep script order!
        t.async = false;
        t.src = url;
        s.parentNode.insertBefore(t, s);
    }
};

Some references backing this logic (and regarding browser support) from MDN and Microsoft

When you add the script tag to the page, the browser has to go out and download those scripts. There's no guarantee that they will download and execute in the same order that you created them.

You will need to add an event listener to new_script for when it loads, either onload or onreadystatechange , depending on the browser. But truly I'd recommend using a script loading library (such as RequireJS ) that handles all the nasty details for you.

As an aside, why not just add all your script tags directly to your page? In that case they load sequentially.

It's better if you resolve this problem using a script loader.

As Matt said RequireJS is a good option if you also want to handle script dependencies.

For script loading only, you can take a look into LAB.js , is very small and straightforward:

for (var index in file_list) {
    $LAB.script(file_list[index]);
}

If the scripts have dependencies and must be loaded in order, you can use .wait() , to do that keep the chain object returned by script. You can re-write the loop to keep the chain:

var chain;
for (var index in file_list) {
    if (!chain) { 
         chain = $LAB.script(file_list[index]).wait(); 
    } else {
         chain.script(file_list[index]).wait();
    }
}

Or just forget the file_list array and use $LAB directly:

$LAB.script('file1.js').wait()
    .script('file2.js').wait()
    /* ... */

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM