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.
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.
-
Add
async
to both and call2.js
after1.js
– Carpetfizz Commented Jan 3, 2016 at 9:13 - 1 =) Of course, I already did it. It doesn't work. – thedriveee Commented Jan 3, 2016 at 9:19
- 1 This might help: stackoverflow./questions/34076200/… – Shanoor Commented Jan 3, 2016 at 9:20
- Use a minifier to minimize and bine the files. That will allow you to use the async attribute and force the script to run in order. – Bindrid Commented Jan 3, 2016 at 9:21
5 Answers
Reset to default 7You 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./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./en/tutorials/speed/script-loading/
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 :)
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:
- JSPM (which uses SystemJS as polyfill to ES2015 module loading).
- Babel transpiler to pile ES2015 to ES 5.x.
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.
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.