8

I have such structure:

<script src="/Content/Scripts/1.js"></script>
<script async src="/Content/Scripts/2.js"></script>

I need to load both files async and run 2.js file after 1.js. How could I do it?

If I add async to 2.js they will run at random.

Nisse Engström
  • 4,738
  • 23
  • 27
  • 42
thedriveee
  • 609
  • 3
  • 9
  • 22

5 Answers5

7

You could dynamically add your scripts, in that way they are loaded asynchronously by default.

To ensure an ordered execution you could mark them explicitly as not async.

Here is a minimum example:

<html>
    <head>
        <script>
            [
                'https://code.jquery.com/jquery-1.11.3.min.js',
                '1.js'
            ].forEach(function(src) {
                var script = document.createElement('script');
                script.src = src;
                script.async = false;
                document.head.appendChild(script);
            });
        </script>
    </head>
    <body>

    </body>
</html>

The File 1.js contains jquery code:

$("body").append("<div>It works</div>");

In this example the files are loaded asynchrounously but keep the specified order. For further reading you can have a look at: http://www.html5rocks.com/en/tutorials/speed/script-loading/

shock_gone_wild
  • 6,700
  • 4
  • 28
  • 52
2

One approach would be to to load the first file(1.js) asynchronously, and then dynamically add the second script as mentioned in the other answer, by making it to load asynchronously.

Load first file:

<script async src="/Content/Scripts/1.js"></script>

Then in the first file, include the following at the bottom,

var script = document.createElement('script');
script.src = "/Content/Scripts/2.js";
script.async = true;
document.head.appendChild(script);

Hope this helps :)

Snazzy Sanoj
  • 804
  • 1
  • 11
  • 28
1

Regular asynchronous scripts doesn't support load ordering. BTW, ES2015 and above have the import syntax to asynchronously-load script files in order:

import x from "x.js";
import y from "y.js";

Or you can also use the programmatic API:

Promise.all([System.import("x.js"), System.import("y.js")]).then(() => {
   // Do stuff once they've been already loaded...
});

If you want to use these features today, you should take a look at:

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
1

Another way could be to use another attribute to store the second's source content

<script async src="/Content/Scripts/1.js"></script>
<script id="second" async data-src="/Content/Scripts/2.js"></script>

and inside the first script after you are finished with the dependent code between the 2 files(if any), write

var script = document.getElementById('second');
script.setAttribute("src",script.getAttribute("data-src"));
script.removeAttribute("data-src"); //Totally upto you if you want to remove it

Compared to the other solutions, this provides you more flexibility in placing the tag anywhere.

  • So you can have as many of those scripts as you want. You should just add `data-id` that increments for every script and at the end of every script check `data-id +1` if exists and if it does do the same process. I think this should be the accepted answer. – temo Mar 01 '19 at 07:33
0

Going from "Abhishek singh" -s answer I created some snippet myself.

You can have as many js files to execute consecutively as you need.

html looks like this:

<title>Script execution sequence</title>
<body>

    <script async data-ascript-id='2' data-src='second.js'></script>
    <script async data-ascript-id='1' data-src='first.js'></script>

    <script async src="pixel.js"></script>

</body>

pixel.js:

console.log("Pixel script executed");

var aon_scripts = document.querySelectorAll('[data-ascript-id]');

if(aon_scripts.length > 0){

    var next_script = document.querySelectorAll('[data-ascript-id="1"]')[0];

    console.log("pixel.js found next script");

    next_script.setAttribute("src", next_script.getAttribute("data-src") );
}

first.js:

console.log("Next script executed");

var current_script = document.currentScript;

var this_script_data_id = current_script.getAttribute("data-ascript-id");

if(aon_scripts.length > parseInt(this_script_data_id) ){

    console.log("There is more script");

    var next_script = document.querySelectorAll('[data-ascript-id="'+                
(parseInt(this_script_data_id) + 1) +'"]')[0];

    next_script.setAttribute("src", next_script.getAttribute("data-src") );

}
else{

    console.log("No more scripts to execute");

}

second.js and all from there will have the same code as first.js.

Output when I have first.js and second.js the same:

pixel.js:      Pixel script executed
pixel.js:11    pixel.js found next script
first.js:1     Next script executed
first.js:9     There is more script
second.js:1    Next script executed
second.js:18   No more scripts to execute

If anyone wants a detailed explanation please let me know.

temo
  • 612
  • 1
  • 9
  • 25